graphene-django-optimizer
graphene-django-optimizer copied to clipboard
TypeError("Cannot call select_related() after .values() or .values_list()")
Python version: 3.8 Django version: 3.1.14
I am a maintainer of Nautobot and we recently implemented the optimizer in our v1.2.0 release. We just got this bug report related to trying to query a related object and filtering only the id
field for it, which results in this error:
{
"errors": [
{
"message": "Cannot call only() after .values() or .values_list()",
"locations": [
{
"line": 5,
"column": 3
}
],
"path": [
"device",
"rel_cluster_to_device"
]
}
],
"data": {
"device": {
"name": "R10-S3",
"rel_cluster_to_device": null
}
}
}
And this server-side traceback:
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: An error occurred while resolving field DeviceType.rel_device_to_vm
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: Traceback (most recent call last):
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphql/execution/executor.py", line 452, in resolve_or_error
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: return executor.execute(resolve_fn, source, info, **args)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphql/execution/executors/sync.py", line 16, in execute
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: return fn(*args, **kwargs)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/nautobot/core/graphql/generators.py", line 139, in resolve_relationship
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: queryset_ids = gql_optimizer.query(
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphene_django_optimizer/query.py", line 40, in query
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: return QueryOptimizer(info, **options).optimize(queryset)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphene_django_optimizer/query.py", line 60, in optimize
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: return store.optimize_queryset(queryset)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphene_django_optimizer/query.py", line 378, in optimize_queryset
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: queryset = queryset.select_related(*self.select_list)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/django/db/models/query.py", line 1047, in select_related
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: raise TypeError("Cannot call select_related() after .values() or .values_list()")
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: TypeError: Cannot call select_related() after .values() or .values_list()
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: Traceback (most recent call last):
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphql/execution/executor.py", line 452, in resolve_or_error
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: return executor.execute(resolve_fn, source, info, **args)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphql/execution/executors/sync.py", line 16, in execute
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: return fn(*args, **kwargs)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/nautobot/core/graphql/generators.py", line 139, in resolve_relationship
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: queryset_ids = gql_optimizer.query(
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphene_django_optimizer/query.py", line 40, in query
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: return QueryOptimizer(info, **options).optimize(queryset)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphene_django_optimizer/query.py", line 60, in optimize
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: return store.optimize_queryset(queryset)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/graphene_django_optimizer/query.py", line 378, in optimize_queryset
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: queryset = queryset.select_related(*self.select_list)
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: File "/opt/nautobot/lib/python3.9/site-packages/django/db/models/query.py", line 1047, in select_related
Jan 04 10:38:42 dh01-a-06-18 nautobot-server[2465943]: raise TypeError("Cannot call select_related() after .values() or .values_list()")
This query reproduces the error:
query {
device(id: "a7c1dcc8-80eb-4754-9981-e2f63a9ab11e") {
id
name
rel_bgp_device_router_id {
id
}
}
}
But the following variant query works just fine:
query {
device(id: "a7c1dcc8-80eb-4754-9981-e2f63a9ab11e") {
id
name
rel_bgp_device_router_id {
id
address
}
}
}
Unfortunately it's non-trivial to try it for yourself. We have a temporary workaround that doesn't fix anything in graphene-django-optimizer
but just wraps the calls in a try...except
block. See: https://github.com/nautobot/nautobot/pull/1230
We'd be happy to try to help fix this bug, but just in case you might be able to fix it quicker, I wanted to report it here. Thanks for this great project!
Summary
- Bug report for Nautobot: https://github.com/nautobot/nautobot/issues/1228
- Workaround for the bug: https://github.com/nautobot/nautobot/pull/1230
Hi @jathanism! This issue skipped my radar and I just noticed because of another one that was reported. If I find time in the future I will try to debug and fix this (I'm a little rusty on Python and this project in general so it can take me some time).