Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flask sqlalchemy 烧瓶+;SQLAlchemy+;pytest-不回滚我的会话_Flask Sqlalchemy_Pytest - Fatal编程技术网

Flask sqlalchemy 烧瓶+;SQLAlchemy+;pytest-不回滚我的会话

Flask sqlalchemy 烧瓶+;SQLAlchemy+;pytest-不回滚我的会话,flask-sqlalchemy,pytest,Flask Sqlalchemy,Pytest,关于堆栈溢出有几个类似的问题,如果我问另一个问题违反了礼仪,我会提前道歉,但我似乎无法想出一套合适的咒语来实现这一点 我尝试使用Flask+Flask SQLAlchemy,然后使用pytest来管理会话,这样当函数范围的pytest夹具被拆除时,当前的事务被回滚 其他一些问题似乎主张在函数范围内使用db“drop all and create all”pytest fixture,但我尝试使用联接会话,并使用回滚,因为我有很多测试。这将大大加快速度 这是我发现原始想法的地方,也是建议使用函数级

关于堆栈溢出有几个类似的问题,如果我问另一个问题违反了礼仪,我会提前道歉,但我似乎无法想出一套合适的咒语来实现这一点

我尝试使用Flask+Flask SQLAlchemy,然后使用pytest来管理会话,这样当函数范围的pytest夹具被拆除时,当前的事务被回滚

其他一些问题似乎主张在函数范围内使用db“drop all and create all”pytest fixture,但我尝试使用联接会话,并使用回滚,因为我有很多测试。这将大大加快速度

这是我发现原始想法的地方,也是建议使用函数级db重新创建的问题之一

我也看到了,但这似乎是由Alchemy 2.1(我正在使用)发布的

我目前(非常小,希望可以立即理解)的回购协议如下:

有两个print语句-第一个(在example/_init__.py中)应该有一个Account对象,第二个(在test/conftest.py中)是在回滚事务后清除db的地方

如果您
pip install-r requirements.txt
并从测试目录运行
py.test-s
,您应该会看到两条打印语句

我在这里快要走到尽头了——一定有什么东西我错过了,但就我的一生而言,我就是找不到


帮帮我,所以,你是我唯一的希望

我的回滚也有问题,可以找到我的代码

在阅读了一些文档之后,似乎应该在会话中调用
begin()
函数

因此,在您的情况下,我会将会话夹具更新为:

@pytest.yield_fixture(scope='function', autouse=True)
def session(db, request):
    """Creates a new database session for a test."""

    db.session.begin()

    yield db.session

    db.session.rollback()
    db.session.remove()
我没有测试这段代码,但在我的代码上尝试时,出现以下错误:

INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "./venv/lib/python2.7/site-packages/_pytest/main.py", line 90, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
...
INTERNALERROR>   File "./venv/lib/python2.7/site-packages/_pytest/python.py", line 59, in filter_traceback
INTERNALERROR>     return entry.path != cutdir1 and not entry.path.relto(cutdir2)
INTERNALERROR> AttributeError: 'str' object has no attribute 'relto'
你可能想试一试。它是一个插件,它公开了一个
db\u会话
fixture,它完成了您所寻找的内容:允许您运行数据库更新,当测试退出时将回滚。该插件基于Alex Michael的博客文章,对嵌套事务提供了一些额外的支持,涵盖了更广泛的用户案例。还有一些用于模拟应用程序中的连接文件的配置选项,这样您也可以从代码库中运行任意方法

对于
test\u accounts.py
,您可以执行以下操作:

from example import db, Account


class TestAccounts(object):

    def test_update_view(self, db_session):

        test_acct = Account(username='abc')

        db_session.add(test_acct)
        db_session.commit()

        resp = self.client.post('/update',
                                data={'a':1},
                                content_type='application/json')

        assert resp.status_code == 200
插件需要通过
\u db
装置访问您的数据库,但由于您已经在
conftest.py
中定义了
db
装置,因此您可以轻松设置数据库访问:

@pytest.fixture(scope='session')
def _db(db):
    return db
您可以在中找到有关如何设置和安装的详细信息。希望这有帮助

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from unittest import TestCase

# global application scope.  create Session class, engine
Session = sessionmaker()

engine = create_engine('postgresql://...')

class SomeTest(TestCase):
    def setUp(self):
        # connect to the database
        self.connection = engine.connect()

        # begin a non-ORM transaction
        self.trans = self.connection.begin()

        # bind an individual Session to the connection
        self.session = Session(bind=self.connection)

    def test_something(self):
        # use the session in tests.

        self.session.add(Foo())
        self.session.commit()

    def tearDown(self):
        self.session.close()

        # rollback - everything that happened with the
        # Session above (including calls to commit())
        # is rolled back.
        self.trans.rollback()

        # return connection to the Engine
        self.connection.close()

当我用上述代码替换会话装置时,它甚至不允许我启动事务:
InvalidRequestError:事务已经开始。使用subtransactions=True来允许子事务。
我认为
\u db.engine.connect()
应该以某种方式将会话“连接”在一起-请看,在这两个github对话的帮助下,我能够在我的示例上实现回滚:对,但这些问题/公关似乎表明249被合并到了Alchemy 2.1中,这就是为什么我认为它会“开箱即用”的原因。我想我会尝试这些补丁,如果它有效,我会回复。