Pergunta

Eu tenho tentado encontrar alguns exemplos de como implementar o padrão de repositório com o SQLalChemy. Especificamente, implementando mais de um repositório.

No caso de vários repositórios, acredito que cada repositório seria melhor implementado, mantendo uma sessão separada de sqlalchemy. No entanto, tenho me dado um problema em tentar mover uma instância de um objeto ligado a uma sessão para outra sessão.

Primeiro, isso faz sentido fazer? Cada repositório deve manter seu próprio Uow separado de qualquer outro repositório ou deve ser considerado seguro ter todo o contexto compartilhar a mesma sessão?

Segundo, qual é a melhor maneira de destacar uma instância de uma sessão e vinculá -la a outra?

Terceiro, existem exemplos sólidos de repositório DDD escritos com sqlalchemy em mente?

Foi útil?

Solução

Não sou familiar com o padrão de repositório DDD, mas abaixo está um exmaple mostrando como mover um objeto de uma sessão para outra:

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top