Skip to content

Commit

Permalink
fix: reference field, cache field refetching data even when field is …
Browse files Browse the repository at this point in the history
…already pre-fetched
  • Loading branch information
mak626 committed Jun 17, 2024
1 parent a577209 commit ea48e20
Showing 1 changed file with 34 additions and 14 deletions.
48 changes: 34 additions & 14 deletions graphene_mongo/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ def convert_field_to_dynamic(field, registry=None, executor: ExecutorEnum = Exec
model = field.document_type

def reference_resolver(root, *args, **kwargs):
document = getattr(root, field.name or field.db_name)
document = root._data.get(field.name or field.db_name, None)
if document:
queried_fields = list()
_type = registry.get_type_for_model(field.document_type, executor=executor)
Expand All @@ -558,16 +558,23 @@ def reference_resolver(root, *args, **kwargs):
item = to_snake_case(each)
if item in field.document_type._fields_ordered + tuple(filter_args):
queried_fields.append(item)

fields_to_fetch = set(list(_type._meta.required_fields) + queried_fields)
if isinstance(document, field.document_type) and all(
document._data[_field] is not None for _field in fields_to_fetch
):
return document # Data is already fetched
return (
field.document_type.objects()
.no_dereference()
.only(*(set(list(_type._meta.required_fields) + queried_fields)))
.only(*fields_to_fetch)
.get(pk=document.id)
)
return None

def cached_reference_resolver(root, *args, **kwargs):
if field:
document = root._data.get(field.name or field.db_name, None)
if document:
queried_fields = list()
_type = registry.get_type_for_model(field.document_type, executor=executor)
filter_args = list()
Expand All @@ -579,16 +586,22 @@ def cached_reference_resolver(root, *args, **kwargs):
item = to_snake_case(each)
if item in field.document_type._fields_ordered + tuple(filter_args):
queried_fields.append(item)

fields_to_fetch = set(list(_type._meta.required_fields) + queried_fields)
if isinstance(document, field.document_type) and all(
document._data[_field] is not None for _field in fields_to_fetch
):
return document # Data is already fetched
return (
field.document_type.objects()
.no_dereference()
.only(*(set(list(_type._meta.required_fields) + queried_fields)))
.only(*fields_to_fetch)
.get(pk=getattr(root, field.name or field.db_name))
)
return None

async def reference_resolver_async(root, *args, **kwargs):
document = getattr(root, field.name or field.db_name)
document = root._data.get(field.name or field.db_name, None)
if document:
queried_fields = list()
_type = registry.get_type_for_model(field.document_type, executor=executor)
Expand All @@ -601,16 +614,20 @@ async def reference_resolver_async(root, *args, **kwargs):
item = to_snake_case(each)
if item in field.document_type._fields_ordered + tuple(filter_args):
queried_fields.append(item)

fields_to_fetch = set(list(_type._meta.required_fields) + queried_fields)
if isinstance(document, field.document_type) and all(
document._data[_field] is not None for _field in fields_to_fetch
):
return document # Data is already fetched
return await sync_to_async(
field.document_type.objects()
.no_dereference()
.only(*(set(list(_type._meta.required_fields) + queried_fields)))
.get
field.document_type.objects().no_dereference().only(*fields_to_fetch).get
)(pk=document.id)
return None

async def cached_reference_resolver_async(root, *args, **kwargs):
if field:
document = root._data.get(field.name or field.db_name, None)
if document:
queried_fields = list()
_type = registry.get_type_for_model(field.document_type, executor=executor)
filter_args = list()
Expand All @@ -622,11 +639,14 @@ async def cached_reference_resolver_async(root, *args, **kwargs):
item = to_snake_case(each)
if item in field.document_type._fields_ordered + tuple(filter_args):
queried_fields.append(item)

fields_to_fetch = set(list(_type._meta.required_fields) + queried_fields)
if isinstance(document, field.document_type) and all(
document._data[_field] is not None for _field in fields_to_fetch
):
return document # Data is already fetched
return await sync_to_async(
field.document_type.objects()
.no_dereference()
.only(*(set(list(_type._meta.required_fields) + queried_fields)))
.get
field.document_type.objects().no_dereference().only(*fields_to_fetch).get
)(pk=getattr(root, field.name or field.db_name))
return None

Expand Down

0 comments on commit ea48e20

Please sign in to comment.