Как мне эффективно использовать SQLAlchemy с несколькими репозиториями DDD?

StackOverflow https://stackoverflow.com/questions/2276523

Вопрос

Я пытался найти несколько примеров того, как реализовать шаблон репозитория с помощью SQLAlchemy.В частности, реализация более чем одного репозитория.

В случае нескольких репозиториев, я считаю, что каждый репозиторий лучше всего реализовать, поддерживая отдельный сеанс SQLAlchemy.Однако я столкнулся с проблемой, пытаясь переместить экземпляр объекта, привязанный к одному сеансу, в другой сеанс.

Во-первых, есть ли смысл это делать?Должен ли каждый репозиторий поддерживать свой собственный UoW отдельно от любого другого репозитория или следует считать безопасным, чтобы весь контекст совместно использовал один и тот же сеанс?

Во-вторых, каков наилучший способ отсоединить экземпляр от одного сеанса и привязать его к другому?

В-третьих, существуют ли какие-либо надежные примеры репозиториев DDD, написанные с учетом SQLAlchemy?

Это было полезно?

Решение

Я не знаком с шаблоном репозитория 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top