我創建圍繞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'解決了這個問題。 –