質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.54%

SQLAlchemyのエラー(UnmappedInstanceError)の原因について

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 204

hiroikawa55

score 17

PostgreSQLに、SQLAlchemyを用いて接続し、モデルを定義の上、フォルダ内のテキスト(Html形式)をデータベースに追加しようとしています。
以下のコードを実行したところ、以下のようなエラーメッセージが出てしまいます。申し訳ありません。どなかたエラーの原因がわかる方、ご教示いただけないでしょうか。
どうぞよろしくお願い申し上げます。


AttributeError                            
Traceback (most recent call last)
/opt/conda/lib/python3.7/site-packages/sqlalchemy/orm/session.py in add(self, instance, _warn)
1942         try:
-> 1943             state = attributes.instance_state(instance)
1944         except exc.NO_STATE:

AttributeError: 'tuple' object has no attribute '_sa_instance_state'

During handling of the above exception, another exception occurred:

UnmappedInstanceError                     
Traceback (most recent call last)
<ipython-input-33-81f0ea7b0027> in <module>
9         print('scraped:', title)
10         url = 'https://ja.wikipedia.org/wiki/{0}'.format(urllib.parse.quote(title))
---> 11         session.add((text, json.dumps({'url': url, 'title': title})))
12     session.commit()
13     session.close()

/opt/conda/lib/python3.7/site-packages/sqlalchemy/orm/session.py in add(self, instance, _warn)
1943             state = attributes.instance_state(instance)
1944         except exc.NO_STATE:
-> 1945             raise exc.UnmappedInstanceError(instance)
1946 
1947         self._save_or_update_state(state)

UnmappedInstanceError: Class 'builtins.tuple' is not mapped

import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
url = URL(drivername='postgresql', username='postgres', password = '<password>', host = 'localhost', database = 'test')
url
engine = create_engine(url)
engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    content = Column(String)
    meta_info = Column(String)

from sqlalchemy.orm import sessionmaker
session = sessionmaker(bind=engine)()
import re
import unicodedata

from bs4 import BeautifulSoup
translation_table = str.maketrans(dict(zip('()!', '()!')))

def cleanse(text):
    text = unicodedata.normalize('NFKC', text).translate(translation_table)
    text = re.sub(r'\s+', ' ', text)
    return text

def scrape(html):
    soup = BeautifulSoup(html, 'html.parser')
    # __EOS__ の挿入
    for block in soup.find_all(['br', 'p', 'h1', 'h2', 'h3', 'h4']):
        if len(block.text.strip()) > 0 and block.text.strip()[-1] not in ['。', '!']:
            block.append('<__EOS__>')
    # 本文の抽出
    text = '\n'.join([cleanse(block.text.strip())
                      for block in soup.find_all(['p', 'h1', 'h2', 'h3', 'h4'])
                      if len(block.text.strip()) > 0])
    # タイトルの抽出
    title = cleanse(soup.title.text.replace(' - Wikipedia', ''))
    return text, title

import glob
import urllib.request
import json
users = []
for filename in glob.glob('./data/wikipedia/*.html'):
    with open(filename) as fin:
        html = fin.read()
        text, title = scrape(html)
        print('scraped:', title)
        url = 'https://ja.wikipedia.org/wiki/{0}'.format(urllib.parse.quote(title))
        session.add((text, json.dumps({'url': url, 'title': title})))
        session.commit()
    session.close()
コード
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

すみません、そもそもの構文が整理されていないので、もう少し検討してから再度質問したいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.54%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる