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

Sqlalchemy:二次関係の更新

    問題は、作成するインスタンスが一意であることを確認する必要があることです。新しいインスタンスを返す前に、既存のコミットされていないインスタンスのキャッシュをチェックしたり、データベースに既存のコミットされたインスタンスを照会したりする代替コンストラクターを作成できます。

    このような方法のデモンストレーションは次のとおりです。

    from sqlalchemy import Column, Integer, String, ForeignKey, Table
    from sqlalchemy.engine import create_engine
    from sqlalchemy.ext.declarative.api import declarative_base
    from sqlalchemy.orm import sessionmaker, relationship
    
    engine = create_engine('sqlite:///:memory:', echo=True)
    Session = sessionmaker(engine)
    Base = declarative_base(engine)
    
    session = Session()
    
    
    class Role(Base):
        __tablename__ = 'role'
    
        id = Column(Integer, primary_key=True)
        name = Column(String, nullable=False, unique=True)
    
        @classmethod
        def get_unique(cls, name):
            # get the session cache, creating it if necessary
            cache = session._unique_cache = getattr(session, '_unique_cache', {})
            # create a key for memoizing
            key = (cls, name)
            # check the cache first
            o = cache.get(key)
            if o is None:
                # check the database if it's not in the cache
                o = session.query(cls).filter_by(name=name).first()
                if o is None:
                    # create a new one if it's not in the database
                    o = cls(name=name)
                    session.add(o)
                # update the cache
                cache[key] = o
            return o
    
    
    Base.metadata.create_all()
    
    # demonstrate cache check
    r1 = Role.get_unique('admin')  # this is new
    r2 = Role.get_unique('admin')  # from cache
    session.commit()  # doesn't fail
    
    # demonstrate database check
    r1 = Role.get_unique('mod')  # this is new
    session.commit()
    session._unique_cache.clear()  # empty cache
    r2 = Role.get_unique('mod')  # from database
    session.commit()  # nop
    
    # show final state
    print session.query(Role).all()  # two unique instances from four create calls
    

    create_unique メソッドは、SQLAlchemywikiの例 に触発されました。 。このバージョンはそれほど複雑ではなく、柔軟性よりも単純さを優先しています。実稼働システムで問題なく使用しました。

    追加できる改善点が明らかにあります。これは単純な例です。 get_unique メソッドはUniqueMixinから継承できます 、任意の数のモデルに使用されます。引数のより柔軟なメモ化を実装できます。これにより、複数のスレッドがAntsAasmaによって言及された競合するデータを挿入するという問題も回避されます。より複雑ですが、明らかな拡張であるはずの処理。任せます。



    1. PDOステートメントが機能しない

    2. MySQL-この表にあるものを除いてすべて選択

    3. mysql_insert_idスレッドは安全ですか?

    4. ソートのためのVarcharから数値への変換