实例“<Ttz at 0x1142ac9d0>”在此会话中不持久

问题描述 投票:0回答:1

我有一些FastAPI应用程序代码:

engine = create_async_engine(settings.DB.async_dns, **settings.DB.OPTIONS)
Session = async_sessionmaker(bind=engine, expire_on_commit=False)
metadata = MetaData()


async def get_session():
    session = Session()
    try:
        yield session
        await session.commit()
    except Exception as e:
        await session.rollback()
        raise e
    finally:
        await session.close()


async def get_active_ttz(session, ttz_id: int):
    stmt = select(Ttz).where(Ttz.id == ttz_id)
    return await session.scalar(stmt)


async def create_file(session, **values):
    instance = TtzFile(**values)
    session.add(instance)
    await session.flush()
    return instance


@router.post("/ttz/{ttz_id}/file")
async def create_ttz_file(ttz_id: PositiveInt, data: TtzFileCreateDataSchema, session: AsyncSession = Depends(get_session)):
    ttz = await get_active_ttz(session, ttz_id)
    ttz_file = await create_file(session, ttz=ttz, **data.model_dump())
    return ttz_file

和一些 Pytest 测试:

@pytest.fixture(autouse=True)
async def session(database, mocker: MockerFixture) -> AsyncGenerator[AsyncSession, None]:
    connection = await engine.connect()
    transaction = await connection.begin()
    session = AsyncSession(bind=connection, expire_on_commit=False, join_transaction_mode="create_savepoint")
    mocker.patch("sqlalchemy.ext.asyncio.session.async_sessionmaker.__call__", return_value=session)
    try:
        yield session
    finally:
        await session.close()
        await transaction.rollback()
        await connection.close()


async def test(session: AsyncSession, client: AsyncClient):
    ttz = Ttz(name="TTZ", start_date=today())
    session.add(ttz)
    await session.commit()

    url = app.url_path_for("create_ttz_file", ttz_id=ttz.id)
    ttz_file_create_payload = fake_ttz_file_create_payload()
    await client.post(url, json=encode_json_payload(ttz_file_create_payload))

    await session.refresh(ttz, attribute_names=["files"])

我面临下一个问题。当我通过 client.post

get_session
发出请求时,依赖项有效。当工作会话关闭时,代码
await session.refresh(ttz, attribute_names=["files"])
失败并出现错误:

sqlalchemy.exc.InvalidRequestError: Instance '<Ttz at 0x1142ac9d0>' is not persistent within this Session

我想为了让它工作,我应该以某种方式将

ttz
实例添加到会话中吗?如果是这样我该怎么做?或者也许有另一种方法可以解决这个问题?

sqlalchemy pytest fastapi
1个回答
0
投票

需要制作

merge
:

ttz = await session.merge(ttz)
await session.refresh(ttz, attribute_names=["files"])
© www.soinside.com 2019 - 2024. All rights reserved.