Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Listing or returning items with UoW raises sqlalchemy.orm.exc.DetachedInstanceError #63

Open
sevetseh28 opened this issue Mar 22, 2023 · 2 comments

Comments

@sevetseh28
Copy link

sevetseh28 commented Mar 22, 2023

Hi. I have a simple list endpoint as follows:

@app.get("/items/", response_model=list[schemas.Item])
async def read_items(uow: AbstractUnitOfWork = Depends(get_uow)) -> List[models.Item]:
    with uow:
        items = uow.repo.list()
    return items

items is a list of models.Item which is my domain model (dataclass). But when exiting the uow (closing the session) the items' attributes are refreshed by the ORM automatically and I get the sqlalchemy.orm.exc.DetachedInstanceError exception.

I would expect such a dataclass not to mutate since it is not an ORM model.
What would be the best approach in this case?

The same applies for the creation of an item.

Thanks!

@sevetseh28
Copy link
Author

sevetseh28 commented Mar 22, 2023

Maybe using schemas.Item as a DTO like this, and convert:

def item_to_schema(item: models.Item) -> schemas.Item:
    return schemas.Item(id=item.id, title=item.title, description=item.description)
@app.get("/items/", response_model=list[schemas.Item])
async def read_items(uow: AbstractUnitOfWork = Depends(get_uow)) -> List[schemas.Item]:
    with uow:
        items = uow.repo.list()
        # Convert items to schemas.Item DTOs
        items_dtos = [item_to_schema(item) for item in items]
    return items_dtos

wdyt?

@instanceofmel
Copy link

A little late, but for future readers:

You have multiple options in this case, including the one @sevetseh28 provided. Other options:

  • Return your list inside the with block
  • Set expire_on_commit=False when creating the session. This will disable the reloading of attributes after commit. I think it's safe to disable it because a handler shouldn't reload anything after commiting anyways as the aggregate must be transactionally consistent and complete before committing.
  • Use a view as described in Chapter 12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants