So let's assume that I try to retrieve all users for Pytest tests as a fixture:
@pytest_asyncio.fixture(scope="function")
async def test_users(db_session):
async with db_session.begin():
cursor = await db_session.execute(
select(User)
)
return cursor.scalars().fetchall()
The thing is that when I try to access objects' attributes in another function (fixture, for example), I get an error sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called.
@pytest_asyncio.fixture(scope="function")
async def another_fixture(test_users: List[User]):
print(test_users[0].id) # sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called
Do I do something wrong? I tried to use db_session.refresh() on each object, but it didn't work.
UPDATE
There is my implementation of db_session fixture:
@pytest_asyncio.fixture(scope="function")
async def db_session():
async with get_db_engine().connect() as connection:
async with get_db_session() as session:
yield session
await connection.rollback()
The reason why you are getting this error is that you are trying to refer to a field outside of the session. You can expunge objects from the session to be able to access them elsewhere. So you'll need to update the test_users
fixture like this.
@pytest_asyncio.fixture(scope="function")
async def test_users(db_session):
async with db_session.begin() as session:
cursor = await session.execute(
select(User)
)
users = cursor.scalars().fetchall()
session.expunge_all()
return users