为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

一只萌萌小番薯 2022-09-13 19:25:54
我使用 测试来覆盖项目。pytest在每个应用程序 () 中,我创建了 ,其中放置了带有 .moduletests folderapplication tests在每个测试文件夹中,每个应用程序都有。conftest fixtures当我为每个应用程序(如pytest应用程序/用户)单独运行测试时,一切正常。但是,当我为第一个应用程序运行整个项目(只是 pytest)的测试时,但随后它会抛出 sqlalchemy.exc.ResourceClosed错误:对于其他应用程序,此连接已关闭错误tests pass示例conftest.pyimport osimport pytestTESTDB = "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)
查看完整描述

1 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

不能同时与 sqlite 数据库建立两个连接。此外,您在这里有两个连接,一个在会话夹具中显式连接,您自己打开和关闭它,第二个隐含在夹具()中,可能关闭不会在这里发生。因此,请尝试仅使用一次隐式连接,而不是 db 和进程夹具仅使进程夹具:db_db.session


@pytest.fixture

def 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拆分为几个单独的夹具,每个夹具用于一个对象,并在确切需要的地方使用它们。


查看完整回答
反对 回复 2022-09-13
  • 1 回答
  • 0 关注
  • 343 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号