sql >> データベース >  >> RDS >> PostgreSQL

Flask-SQLAlchemy db.session.query(Model)とModel.query

    モデルインスタンスに変更を加えてデータベースにコミットする正しい方法は次のとおりです。

    # 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つ作成し、モデルの宣言からクエリまで、あらゆる場所で使用します。



    1. count(*)とnum_rowsの使用

    2. 常にnvarchar(MAX)を使用することに不利な点はありますか?

    3. PostGISを使用して特定のポイントのn最近傍を検索しますか?

    4. Rails-複数の関係にわたってデータを効率的にプルして計算します