如何在异步FastAPI测试中使用PostgreSQL测试数据库?

juzqafwq  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(320)

我正在做一个异步FastAPI项目,我想在测试期间连接到数据库。来自Django,我的直觉是创建pytest fixture来负责创建/删除测试数据库。但是,我找不到很多关于如何做的文档。我能找到的最完整的说明在this tutorial中,但是它们对我不起作用,因为它们都是同步的。我对异步开发有点陌生,所以我在修改代码以使其异步工作时遇到了麻烦。这是我目前所拥有的:

import pytest
from sqlalchemy.ext.asyncio import create_async_engine, session
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy_utils import database_exists, create_database

from fastapi.testclient import TestClient

from app.core.db import get_session
from app.main import app

Base = declarative_base()

@pytest.fixture(scope="session")
def db_engine():
    default_db = (
        "postgresql+asyncpg://postgres:postgres@postgres:5432/postgres"
    )
    test_db = "postgresql+asyncpg://postgres:postgres@postgres:5432/test"
    engine = create_async_engine(default_db)
    if not database_exists(test_db):  # <- Getting error on this line
        create_database(test_db)

    Base.metadata.create_all(bind=engine)
    yield engine

@pytest.fixture(scope="function")
def db(db_engine):
    connection = db_engine.connect()

    # begin a non-ORM transaction
    connection.begin()

    # bind an individual Session to the connection
    Session = sessionmaker(bind=connection)
    db = Session()
    # db = Session(db_engine)

    yield db

    db.rollback()
    connection.close()

@pytest.fixture(scope="function")
def client(db):
    app.dependency_overrides[get_session] = lambda: db

    PREFIX = "/api/v1/my-endpoint"
    with TestClient(PREFIX, app) as c:
        yield c

这就是我得到的错误:

E           sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/14/xd2s)

/usr/local/lib/python3.9/site-packages/sqlalchemy/util/_concurrency_py3k.py:67: MissingGreenlet

你知道我该怎么做才能修好它吗

niwlg2el

niwlg2el1#

您尝试将sync引擎与async会话一起使用。请尝试用途:

from sqlalchemy.ext.asyncio import AsyncSession
Session = sessionmaker(bind= connection, class_=AsyncSession)

https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html

相关问题