graphql-python / graphene-django

Build powerful, efficient, and flexible GraphQL APIs with seamless Django integration.
http://docs.graphene-python.org/projects/django/en/latest/
MIT License
4.31k stars 769 forks source link

Dataloaders not working #1425

Open alexandrubese opened 1 year ago

alexandrubese commented 1 year ago

Hi, I have read the documentation around data loaders from your site, but I can't make them to work. I followed exactly your examples but when I run the Query I get:

INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) /Users/alexandrubese/Documents/work/banking_api/venv/lib/python3.10/site-packages/graphql/execution/execute.py:431: RuntimeWarning: coroutine 'Query.resolve_account' was never awaited result = self.execute_field( RuntimeWarning: Enable tracemalloc to get the object allocation traceback

account_dataloader.py

from aiodataloader import DataLoader
from core.models import Account

def get_account(id):
    return Account.objects.get(pk=id)

class AccountLoader(DataLoader):
    async def batch_load_fn(self, keys):
        return [get_account(id=key) for key in keys]

schema.py

class Account(ObjectType):
    id = ID()
    name = String()
    email = String()
    city = String()
    canton = String()
    toy_category_preference = List(Int)
    toy_size_preference = List(Int)

class Query(ObjectType):
    hello = String(default_value="Hi!")
    account = Field(Account, id=ID(required=True))

    async def resolve_account(root, info, id):
        account_data = await AccountLoader().load(id)
        return account_data

What am I doing wrong?

belkka commented 1 year ago

Could you provide links to the doc and examples you followed? I found this https://docs.graphene-python.org/en/latest/execution/dataloader/.

RuntimeWarning: coroutine 'Query.resolve_account' was never awaited What am I doing wrong?

Apparently, you define an async resolver in a query.

Looks like in order to properly run async resolvers in queries, one have to use Schema.execute_async instead of Schema.execute and the latter is poorly documented. In fact, I only found a brief mention of this in API reference, but not in any other parts of the docs, so this is only my assumption.

It also looks like graphene-django only use Schema.execute, as I do not find matches for .execute_async in the source code. The "Subscriptions" section of graphene-django docs says that even for subscriptions you have to install and configure additional tools (you need to use websockets and ASGI).

The last example at https://docs.graphene-python.org/en/latest/execution/dataloader/ has async resolvers in graphene.ObjectType. It may be correct (for queries executed via Schema.execute_async or for subscriptions), but misleading, as documentation does not really mention how to work with async resolvers. I think docs should be updated to provide clarifications on this.

belkka commented 1 year ago

Oh, just noticed this issue is a duplicate of #1390. It also mentions PR #1394, which aims to add support for Schema.execute_async

pfcodes commented 11 months ago

So in other words, until Schema.execute_async is implemented, there's no way to use Dataloaders with graphene_django?

alexandrubese commented 11 months ago

Any updates?