sqlalchemy.exc.ResourceC 已关闭错误: 此连接已关闭错误

我使用 测试来覆盖项目。pytest


在每个应用程序 () 中,我创建了 ,其中放置了带有 .moduletests folderapplication tests


在每个测试文件夹中,每个应用程序都有。conftest fixtures


当我为每个应用程序(如pytest应用程序/用户)单独运行测试时,一切正常。


但是,当我为第一个应用程序运行整个项目(只是 pytest)的测试时,但随后它会抛出 sqlalchemy.exc.ResourceClosed错误:对于其他应用程序,此连接已关闭错误tests pass


示例conftest.py


import os


import pytest



TESTDB = "test.db"

TESTDB_PATH = os.path.join(basedir, TESTDB)



@pytest.fixture(scope="session")

def app(request):

    """Session-wide test `Flask` application."""

    app = create_app("config.TestConfig")

    # Establish an application context before running the tests.

    ctx = app.app_context()

    ctx.push()


    def teardown():

        ctx.pop()


    request.addfinalizer(teardown)

    return app



@pytest.fixture(scope="session")

def db(app, request):

    """Session-wide test database."""

    if os.path.exists(TESTDB_PATH):

        os.unlink(TESTDB_PATH)


    def teardown():

        _db.drop_all()

        try:

            os.unlink(TESTDB_PATH)

        except FileNotFoundError:

            pass


    _db.app = app

    _db.create_all()


    permission = PermissionModel(title="can_search_articles")

    role = RoleModel(title="API User", permissions=[permission])

    tag = TagModel(name="Test tag")

    article = ArticleModel(

        title="Test article",

        legal_language="en",

        abstract="",

        state="Alaska",

        tags=[tag],

    )

    _db.session.add_all([role, permission, tag, article])

    _db.session.commit()


    user1 = UserModel(email="test@gmail.com", role_id=role.id)

    user2 = UserModel(email="test2@gmail.com")

    _db.session.add_all([user1, user2])


    # Commit the changes for the users

    _db.session.commit()


    request.addfinalizer(teardown)

    return _db



@pytest.fixture(scope="function")

def session(db, request):

    """Creates a new database session for a test."""

    connection = db.engine.connect()

    transaction = connection.begin()


    options = dict(bind=connection, binds={})

    session = db.create_scoped_session(options=options)




一只萌萌小番薯
浏览 344回答 1
1回答

三国纷争

不能同时与 sqlite 数据库建立两个连接。此外,您在这里有两个连接,一个在会话夹具中显式连接,您自己打开和关闭它,第二个隐含在夹具()中,可能关闭不会在这里发生。因此,请尝试仅使用一次隐式连接,而不是 db 和进程夹具仅使进程夹具:db_db.session@pytest.fixturedef session(app):    """Creates a new database session for a test."""    db.app = app    db.create_all()    with db.engine.connect() as connection:        with connection.begin() as transaction:            options = dict(bind=connection, binds={})            session = db.create_scoped_session(options=options)            db.session = session            prepare_data(session)            yield session            transaction.rollback()            db.drop_all()这里prepare_data是你的数据填充新数据库:def prepare_data(session):    permission = PermissionModel(title="can_search_articles")    role = RoleModel(title="API User", permissions=[permission])    tag = TagModel(name="Test tag")    article = ArticleModel(        title="Test article",        legal_language="en",        abstract="",        state="Alaska",        tags=[tag],    )    session.add_all([role, permission, tag, article])    session.commit()    user1 = UserModel(email="test@gmail.com", role_id=role.id)    user2 = UserModel(email="test2@gmail.com")    session.add_all([user1, user2])    # Commit the changes for the users    session.commit()因为这里的会话夹具是函数范围的,所以在每个测试中,你都会有一个数据库。更实用的是,不要每次都完全填满数据库,而是将此prepare_data拆分为几个单独的夹具,每个夹具用于一个对象,并在确切需要的地方使用它们。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python