モデルインスタンスに変更を加えてデータベースにコミットする正しい方法は次のとおりです。
# get an instance of the 'Entry' model
entry = Entry.query.get(1)
# change the attribute of the instance; here the 'name' attribute is changed
entry.name = 'New name'
# now, commit your changes to the database; this will flush all changes
# in the current session to the database
db.session.commit()
注: SQLALCHEMY_COMMIT_ON_TEARDOWN
は使用しないでください 、有害であると見なされ、ドキュメントからも削除されているため。 バージョン2.0の変更ログ
を参照してください。 。
編集: 通常のセッションのオブジェクトが2つある場合 (sessionmaker()
を使用して作成 )スコープセッションの代わりに 、次にdb.session.add(entry)
を呼び出すと 上記のコードはエラーを発生させますsqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3')
。 sqlalchemyセッションの詳細については、以下のセクションをお読みください
スコープセッションと通常セッションの主な違い
主にsessionmaker()
から構築したセッションオブジェクト 呼び出しとデータベースとの通信に使用されるのは通常のセッションです 。 sessionmaker()
を呼び出す場合 2回目は、状態が前のセッションから独立している新しいセッションオブジェクトを取得します。たとえば、次のように構築された2つのセッションオブジェクトがあるとします。
from sqlalchemy import Column, String, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)
from sqlalchemy import create_engine
engine = create_engine('sqlite:///')
from sqlalchemy.orm import sessionmaker
session = sessionmaker()
session.configure(bind=engine)
Base.metadata.create_all(engine)
# Construct the first session object
s1 = session()
# Construct the second session object
s2 = session()
その場合、同じUserオブジェクトを両方のs1
に追加することはできません。 およびs2
同時に。つまり、オブジェクトをアタッチできるのは、最大で1つの一意のセッションオブジェクトのみです。
>>> jessica = User(name='Jessica')
>>> s1.add(jessica)
>>> s2.add(jessica)
Traceback (most recent call last):
......
sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3')
セッションオブジェクトがscoped_session
から取得された場合 ただし、オブジェクトの場合、scoped_session
以降、このような問題は発生しません。 オブジェクトは、同じセッションオブジェクトのレジストリを維持します。
>>> session_factory = sessionmaker(bind=engine)
>>> session = scoped_session(session_factory)
>>> s1 = session()
>>> s2 = session()
>>> jessica = User(name='Jessica')
>>> s1.add(jessica)
>>> s2.add(jessica)
>>> s1 is s2
True
>>> s1.commit()
>>> s2.query(User).filter(User.name == 'Jessica').one()
s1
に注意してください およびs2
どちらもscoped_session
から取得されるため、同じセッションオブジェクトです。 同じセッションオブジェクトへの参照を維持するオブジェクト。
ヒント
したがって、複数の通常のセッションを作成しないようにしてください 物体。セッションのオブジェクトを1つ作成し、モデルの宣言からクエリまで、あらゆる場所で使用します。