3

SQLAlchemy を使用してリポジトリ パターンを実装する方法の例をいくつか見つけようとしています。具体的には、複数のリポジトリを実装します。

複数のリポジトリの場合、各リポジトリは個別の SQLAlchemy セッションを維持することによって最適に実装されると思います。ただし、あるセッションにバインドされたオブジェクトのインスタンスを別のセッションに移動しようとすると、問題が発生します。

まず、これは意味がありますか?各リポジトリは、他のリポジトリとは別に独自の UoW を維持する必要がありますか?それとも、コンテキスト全体が同じセッションを共有しても安全であると見なすべきですか?

次に、あるセッションからインスタンスを切り離し、別のセッションにバインドする最良の方法は何ですか?

第三に、SQLAlchemy を念頭に置いて書かれた確かな DDD リポジトリの例はありますか?

4

1 に答える 1

3

私は DDD リポジトリ パターンに精通していませんが、以下は、あるセッションから別のセッションにオブジェクトを移動する方法を示す例です。

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

metadata  = MetaData()
Base = declarative_base(metadata=metadata, name='Base')

class Model(Base):
    __tablename__ = 'models'
    id = Column(Integer, primary_key=True)


engine1 = create_engine('sqlite://')
metadata.create_all(engine1)
engine2 = create_engine('sqlite://')
metadata.create_all(engine2)

session1 = sessionmaker(bind=engine1)()
session2 = sessionmaker(bind=engine2)()

# Setup an single object in the first repo.
obj = Model()
session1.add(obj)
session1.commit()
session1.expunge_all() 

# Move object from the first repo to the second.
obj = session1.query(Model).first()
assert session2.query(Model).count()==0
session1.delete(obj)
# You have to flush before expunging, otherwise it won't be deleted.
session1.flush()
session1.expunge(obj)
obj = session2.merge(obj)
# An optimistic way to bind two transactions is flushing before commiting.
session2.flush()
session1.commit()
session2.commit()
assert session1.query(Model).count()==0
assert session2.query(Model).count()==1
于 2010-02-17T10:04:39.937 に答える