2010-02-16 49 views
2

我一直在試圖找到一些如何用SQLAlchemy實現存儲庫模式的例子。具體來說,實施多個存儲庫。如何有效地將SQLAlchemy與多個DDD存儲庫一起使用?

對於多個存儲庫,我相信每個存儲庫最好通過維護一個單獨的SQLAlchemy會話來實現。但是,我試圖將綁定到一個會話的對象的實例移動到另一個會話時遇到了問題。

首先,這樣做有意義嗎?每個存儲庫是否應該將自己的UoW與其他存儲庫分開保存,還是應該認爲整個上下文共享同一個Session是安全的?

其次,從一個Session中分離實例並將其綁定到另一個會話的最佳方式是什麼?

第三,有沒有用SQLAlchemy編寫的任何可靠的DDD Repository示例?

回答

2

我不familar與DDD Repository模式,但下面是一個〔實施例展示如何將對象從一個會話移動到另一個:

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 
+0

我實際上並不需要從第一屆刪除對象(我相信這實際上會發出DELETE語句?),我只需要將它分開,以便它可以添加到第二個會話中。如果這是我唯一的目標,我需要做什麼? –

+0

'session1.expunge(obj)'是將對象從會話中分離出來的那一行。我的代碼將對象從一個數據庫移到另一個數據庫。兩個會話您可能都需要單引擎。 –

相關問題