我创建围绕SQLAlchemy的数据库引擎/连接/会话中的“经理”对象:创建事务回滚操作DB围绕这一`Manager`结构
Base = declarative_base()
class Manager(object):
def __init__(self, connection: str = 'sqlite://'):
self.engine = create_engine(connection, echo=True)
Base.metadata.create_all(self.engine)
self.sessionmaker = sessionmaker(bind=self.engine)
self.session = scoped_session(self.sessionmaker)
def do_db_stuff(self):
self.session.query(Whatever).all()
def ensure_thing(self):
thing = Thing()
self.session.add(thing)
self.session.commit()
我想创建两个py.test fixtures:一个实例化管理器,一个在可能调用commit的测试中打包和回滚事务。 This is the pattern我试图跟随,但没有成功:即使通过上述棒调用transaction.rollback()
后周围环绕Manager创建
@pytest.fixture(scope='session')
def manager():
m = Manager()
return m
@pytest.fixture(scope='function')
def manager_session(manager):
connection = manager.session.connection()
transaction = connection.begin()
yield manager
manager.session.close()
transaction.rollback()
connection.close()
不幸的是,对象。
在这样的现有会话周围包装事务的正确方法是什么?
编辑:
另外,不同的尝试:
@pytest.fixture(scope='function')
def manager_session(manager):
connection = manager.engine.connect()
transaction = connection.begin()
manager.sessionmaker.configure(bind=connection)
yield manager
manager.session.close()
transaction.rollback()
编辑2:
,似乎工作,在Ilja Everilä's answer below提到需要提醒的是线程代码会造成麻烦第三次尝试。
@pytest.fixture(scope='session')
def manager():
return Manager()
@pytest.fixture(scope='function')
def manager_transaction(manager):
connection = manager.engine.connect()
transaction = connection.begin()
manager.session_maker.configure(bind=connection)
yield manager
manager.session_maker.configure(bind=manager.engine)
manager.session.remove()
transaction.rollback()
connection.close()
第二次尝试失败了吗? –
第一次测试使用完成的夹具并开始第二次测试后出现故障。我认为(但我不确定)尽管我已经关闭了第二次测试,但仍然获得了同一场会议。看来,切换到'session.remove'解决了这个问题。 –