igorbenav / fastcrud

FastCRUD is a Python package for FastAPI, offering robust async CRUD operations and flexible endpoint creation utilities.
MIT License
530 stars 32 forks source link

Unexpected await_only() issue #99

Closed iameo closed 3 weeks ago

iameo commented 4 weeks ago

FastCrud behaves unexpectedly with relationship (sqlalchemy). For a start I have noticed that Foreignkey are defaulted to None if there's a relationship through the FK.

ERROR: {'type': 'get_attribute_error', 'loc': ('response', 'user'), 'msg': "Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)", 'input': Entity(id=UUID('18baaf7d-b11c-4ea4-994c-xxxxxxx')), 'ctx': {'error': "MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)"}}

To Reproduce

Please provide a self-contained, minimal, and reproducible example of your use case


class Base(DeclarativeBase, MappedAsDataclass):
    pass

class Entity(Base):
   id: Mapped[uuid.Uuid] = mapped_column(primary_key=True)
   user_id: Mapped[uuid.Uuid] = mapped_column(ForeignKey("users.id"))
   user: Mapped["User"] = relationship("User", back_populates="xer")

#It works when I uncomment user from entityRead 

#shema.py

class entityRead(BaseModel):
   id: uuid.UUID
   user: Optional[list[UserRead]] = None

#route.py

@router.post("/entity", status_code=201)
async def write_entity(request Request, entity: EntityCreate):
   ....
   entity_in = EntityCreateInternal(**processed_dict)
   created_entity: entityRead = await crud_entities.create(db=db, object=entity_in)  
   print(created_entity) #FAILS
   return created_entity

#If I use create without `entityRead` then this works too.

   created_entity = await crud_entities.create(db=db, object=entity_in) 
   print(created_entity) #SUCCEEDS
   return created_entity

Expected behaviour would be to create the entity without the issue - the error is invoked but I can see the data in the DB.

I understand that Sqlalchemy is complaining due to Eager Loading but how does this work as expected with FastCrud?

I am looking to change Base to:

class Base(DeclarativeBase, AsyncAttrs):
    pass

Edited: I added the versions for SQLAlchemy and FastCrud. SQLAlchemy 2.0.23 and FastCrud 0.13.0

igorbenav commented 4 weeks ago

That's weird, I'll take a look.

iameo commented 3 weeks ago

I am closing this down as I can confirm it is a SQLAlchemy issue and not FastCrud; the issue pertains to relationship. My bad.