简体   繁体   English

带有 sqlalchemy db 连接的 Pytest 在后续测试用例中终止

[英]Pytest with sqlalchemy db conection terminates in subsequent test case

I am using a sqlalchemy engine connection as a pytest fixture as a way to test functions that require database interaction.我使用 sqlalchemy 引擎连接作为 pytest 固定装置来测试需要数据库交互的函数。 When I run the test cases individually by running pytest tests/filename.py::test_get_token_data or pytest tests/filename.py::test_create the test passes;当我通过运行pytest tests/filename.py::test_get_token_datapytest tests/filename.py::test_create单独运行pytest tests/filename.py::test_create ,测试通过; however, when running the entire test case, pytest tests/filename.py , I get the following error:但是,在运行整个测试用例pytest tests/filename.py ,出现以下错误:

E       sqlalchemy.exc.OperationalError: (psycopg2.errors.AdminShutdown) terminating connection due to administrator command
E       server closed the connection unexpectedly
E               This probably means the server terminated abnormally
E               before or while processing the request.
(Background on this error at: http://sqlalche.me/e/13/e3q8)

To my understanding, after each test, the database is suppose to be cleared (which I've confirmed), however, I do not understand the error.据我了解,每次测试后,数据库都应该被清除(我已经确认),但是,我不明白这个错误。 My code below.我的代码如下。

conftest.py conftest.py

@pytest.fixture
def db_connection(test_config, admin_db_connection):
    config = test_config()
    engine = sqlalchemy.create_engine(config.DB_URL)
    connection = engine.connect()
    yield connection
    connection.close()

    # clear database
    from psycopg2.extensions import AsIs  # handle SQL quoting

    with admin_db_connection.cursor() as curs:
        curs.execute("drop database %s with (force);", (AsIs(config.DB_NAME),))
        curs.execute(
            "create database %s template vtag_template;", (AsIs(config.DB_NAME),)
        )

filename.py文件名.py

import sqlalchemy as sa


@pytest.fixture
def db_injection(db_connection):
    with db_connection.begin():
        some_value = db_connection.execute(
            sa.sql.text(
                """insert into general.some_table as t (some_id, name, description, is_active) values (:some_id, :name, :description, :is_active) returning t.some_id;

                """
            ),
            tenant_id='1234',
            description="TEST",
            is_active=True,
            name="TEST",
        )
        tenant_id_ = some_value.first()[0]
         
                
@pytest.fixture
def some_function(db_connection):

    with db_connection.begin():
        some_table = db_connection.execute(
            sa.sql.text(
                """
                SELECT e.name
                FROM general.some_table e
                WHERE e.id = 1234
            """
            )
        )
    return some_table.first()


def test_get_token_data(client, headers_with_token, db_injection, some_function):

    token = some_function.name
    #API is using the same db connection 
    response = client.get(f"/api/v2/{token}", headers=headers_with_token)

    assert response.status_code == 200


def test_create(client, img, b_64, headers_with_token, db_injection):

    items = Items(
        user_id=1234,
        template_id=67,
        b_64=b_64,
    )

    data = {
        "json": json.dumps(asdict(items)),
        "file": ("some_name", img, "multipart/form-data"),
    }

    response = client.post(
        "/api/v2/create",
        data=data,
        follow_redirects=True,
        content_type="multipart/form-data",
        headers=headers_with_token
    )

    assert response.status_code == 200

The issue was due to the application having an unbinded Session being used.问题是由于应用程序使用了未绑定的会话 Since most of our application us using sqlalchemy's Engine API, we decide with refactor in using raw sql via with engine.begin() .由于我们的大多数应用程序都使用 sqlalchemy 的引擎API,因此我们决定通过with engine.begin()重构使用原始 sql。 Another alternative solution could have been adding the engine into the session另一种替代解决方案可能是将engine添加到会话中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM