strawberry-graphql / strawberry-sqlalchemy

A SQLAlchemy Integration for strawberry-graphql
MIT License
91 stars 26 forks source link

The unique() method must be invoked on this Result, as it contains results that include joined eager loads against collections #13

Closed abettke closed 1 year ago

abettke commented 1 year ago

First off, great job on this library overall. It has made integrating graphql with sqlalchemy a breeze.

I've run into this issue when setting up a pretty basic implementation using this library. The schema loads, but whenever I attempt to query nested relationships using the built-in dataloader sqlalchemy raises this error. I've tracked this down to the load_fn at loader.py line 37. Simply adding a .unique() to the call at rows = self.bind.scalars(query).all() fixes the issue.

sqlalchemy.exc.InvalidRequestError: The unique() method must be invoked on this Result, as it contains results that include joined eager loads against collections
# raises InvalidRequestError
rows = self.bind.scalars(query).all()

# works
rows = self.bind.scalars(query).unique().all()
abettke commented 1 year ago

Figured out the issue within a couple hours after posting this. The problem lies in the fact that the model I was accessing through the relationship was eager loading a tertiary model. Simply disabling that default eager loading also fixes the issue.

Additionally, you can keep the default eager loading defined in the model as long as the query in the resolver specifies that a relationship is already eagerly loaded in the options.

from strawberry import type, field
from sqlalchemy.orm import contains_eager
from db import models

@type
class Query:
    @field
    def my_models(self) -> List[MyModel]:
         models.MyModel.query.options(contains_eager('children.grandchildren')).all()