【发布时间】:2021-02-26 14:41:57
【问题描述】:
我正在研究“Cosmic Python”一书,第 6 章解释了如何使用工作单元模式来更改与数据库/存储库的交互。
本书的第 6 章可在此处访问: https://www.cosmicpython.com/book/chapter_06_uow.html
作者提供的代码如下:
from __future__ import annotations
import abc
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.session import Session
from allocation import config
from allocation.adapters import repository
class AbstractUnitOfWork(abc.ABC):
products: repository.AbstractRepository
def __enter__(self) -> AbstractUnitOfWork:
return self
def __exit__(self, *args):
self.rollback()
@abc.abstractmethod
def commit(self):
raise NotImplementedError
@abc.abstractmethod
def rollback(self):
raise NotImplementedError
DEFAULT_SESSION_FACTORY = sessionmaker(bind=create_engine(
config.get_postgres_uri(),
isolation_level="REPEATABLE READ",
))
class SqlAlchemyUnitOfWork(AbstractUnitOfWork):
def __init__(self, session_factory=DEFAULT_SESSION_FACTORY):
self.session_factory = session_factory
def __enter__(self):
self.session = self.session_factory() # type: Session
self.products = repository.SqlAlchemyRepository(self.session)
return super().__enter__()
def __exit__(self, *args):
super().__exit__(*args)
self.session.close()
def commit(self):
self.session.commit()
def rollback(self):
self.session.rollback()
我正在尝试在 Flask 上测试我的端点,但我无法让它回滚每次测试后插入的数据。
为了解决我尝试安装包pytest-flask-sqlalchemy但出现以下错误:
'SqlAlchemyUnitOfWork' object has no attribute 'engine'
我不太了解pytest-flask-sqlalchemy 的工作原理,也不知道如何在测试后使工作单元回滚事务。
是否可以让它按照作者实现的方式工作?
已编辑
可以通过以下存储库复制我的情况:
https://github.com/Santana94/CosmicPythonRollbackTest
您应该通过克隆测试并运行make all 来了解测试不会回滚之前的操作。
【问题讨论】:
-
好的,我想这就是你问题的重点,哈哈
-
这正是我想要解决的问题。主要问题是在测试完成后每个数据库更改都会保留,因此我的测试在执行回滚事务之前无法工作。
-
我同意你的观点,这很难,正常的程序应该是实现 DI 以隔离所有内容并使对象更易于测试。我正在尝试从
SqlAlchemyUnitOfWork类中模拟会话以尝试使其回滚事务。 -
我认为我的解决方案有效。我设法通过
conftest.py的更正使会话回滚 -
一旦找到可行的解决方案,不要忘记发布您自己问题的答案。
标签: python flask sqlalchemy pytest unit-of-work