Skip to content

Commit 0abaa56

Browse files
authored
feat: support for new graphene-federation (#237)
* bump: v0.4.4 Added support for new graphene-federation Drop support for python 3.8 * fix: reference field, cache field refetching data even when field is already pre-fetched
1 parent 8fd26f2 commit 0abaa56

File tree

7 files changed

+244
-215
lines changed

7 files changed

+244
-215
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
strategy:
1818
matrix:
1919
os: [ubuntu-latest, macos-latest, windows-latest]
20-
python: ["3.8", "3.9", "3.10", "3.11","3.12"]
20+
python: ["3.9", "3.10", "3.11","3.12"]
2121
runs-on: ${{ matrix.os }}
2222
steps:
2323
- uses: actions/checkout@v3

.github/workflows/publish.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
matrix:
1414
os: [ubuntu-latest, macos-latest, windows-latest]
15-
python: ["3.8", "3.9", "3.10", "3.11", "3.12"]
15+
python: ["3.9", "3.10", "3.11", "3.12"]
1616
runs-on: ${{ matrix.os }}
1717
steps:
1818
- uses: actions/checkout@v3

examples/django_mongoengine/requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Django==3.2.24
1+
Django==3.2.25
22
pytest==4.6.3
33
pytest-django==3.5.1
44
mongoengine==0.27.0

graphene_mongo/advanced_types.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import base64
22

33
import graphene
4+
from graphene_federation import shareable
45

56

7+
@shareable # Support Graphene Federation v2
68
class FileFieldType(graphene.ObjectType):
79
content_type = graphene.String()
810
md5 = graphene.String()
911
chunk_size = graphene.Int()
1012
length = graphene.Int()
1113
data = graphene.String()
1214

13-
# Support Graphene Federation v2
14-
_shareable = True
15-
1615
@classmethod
1716
def _resolve_fs_field(cls, field, name, default_value=None):
1817
v = getattr(field.instance, field.key)
@@ -38,12 +37,10 @@ def resolve_data(self, info):
3837
return None
3938

4039

40+
@shareable # Support Graphene Federation v2
4141
class _CoordinatesTypeField(graphene.ObjectType):
4242
type = graphene.String()
4343

44-
# Support Graphene Federation v2
45-
_shareable = True
46-
4744
def resolve_type(self, info):
4845
return self["type"]
4946

graphene_mongo/converter.py

+34-14
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ def convert_field_to_dynamic(field, registry=None, executor: ExecutorEnum = Exec
545545
model = field.document_type
546546

547547
def reference_resolver(root, *args, **kwargs):
548-
document = getattr(root, field.name or field.db_name)
548+
document = root._data.get(field.name or field.db_name, None)
549549
if document:
550550
queried_fields = list()
551551
_type = registry.get_type_for_model(field.document_type, executor=executor)
@@ -558,16 +558,23 @@ def reference_resolver(root, *args, **kwargs):
558558
item = to_snake_case(each)
559559
if item in field.document_type._fields_ordered + tuple(filter_args):
560560
queried_fields.append(item)
561+
562+
fields_to_fetch = set(list(_type._meta.required_fields) + queried_fields)
563+
if isinstance(document, field.document_type) and all(
564+
document._data[_field] is not None for _field in fields_to_fetch
565+
):
566+
return document # Data is already fetched
561567
return (
562568
field.document_type.objects()
563569
.no_dereference()
564-
.only(*(set(list(_type._meta.required_fields) + queried_fields)))
570+
.only(*fields_to_fetch)
565571
.get(pk=document.id)
566572
)
567573
return None
568574

569575
def cached_reference_resolver(root, *args, **kwargs):
570-
if field:
576+
document = root._data.get(field.name or field.db_name, None)
577+
if document:
571578
queried_fields = list()
572579
_type = registry.get_type_for_model(field.document_type, executor=executor)
573580
filter_args = list()
@@ -579,16 +586,22 @@ def cached_reference_resolver(root, *args, **kwargs):
579586
item = to_snake_case(each)
580587
if item in field.document_type._fields_ordered + tuple(filter_args):
581588
queried_fields.append(item)
589+
590+
fields_to_fetch = set(list(_type._meta.required_fields) + queried_fields)
591+
if isinstance(document, field.document_type) and all(
592+
document._data[_field] is not None for _field in fields_to_fetch
593+
):
594+
return document # Data is already fetched
582595
return (
583596
field.document_type.objects()
584597
.no_dereference()
585-
.only(*(set(list(_type._meta.required_fields) + queried_fields)))
598+
.only(*fields_to_fetch)
586599
.get(pk=getattr(root, field.name or field.db_name))
587600
)
588601
return None
589602

590603
async def reference_resolver_async(root, *args, **kwargs):
591-
document = getattr(root, field.name or field.db_name)
604+
document = root._data.get(field.name or field.db_name, None)
592605
if document:
593606
queried_fields = list()
594607
_type = registry.get_type_for_model(field.document_type, executor=executor)
@@ -601,16 +614,20 @@ async def reference_resolver_async(root, *args, **kwargs):
601614
item = to_snake_case(each)
602615
if item in field.document_type._fields_ordered + tuple(filter_args):
603616
queried_fields.append(item)
617+
618+
fields_to_fetch = set(list(_type._meta.required_fields) + queried_fields)
619+
if isinstance(document, field.document_type) and all(
620+
document._data[_field] is not None for _field in fields_to_fetch
621+
):
622+
return document # Data is already fetched
604623
return await sync_to_async(
605-
field.document_type.objects()
606-
.no_dereference()
607-
.only(*(set(list(_type._meta.required_fields) + queried_fields)))
608-
.get
624+
field.document_type.objects().no_dereference().only(*fields_to_fetch).get
609625
)(pk=document.id)
610626
return None
611627

612628
async def cached_reference_resolver_async(root, *args, **kwargs):
613-
if field:
629+
document = root._data.get(field.name or field.db_name, None)
630+
if document:
614631
queried_fields = list()
615632
_type = registry.get_type_for_model(field.document_type, executor=executor)
616633
filter_args = list()
@@ -622,11 +639,14 @@ async def cached_reference_resolver_async(root, *args, **kwargs):
622639
item = to_snake_case(each)
623640
if item in field.document_type._fields_ordered + tuple(filter_args):
624641
queried_fields.append(item)
642+
643+
fields_to_fetch = set(list(_type._meta.required_fields) + queried_fields)
644+
if isinstance(document, field.document_type) and all(
645+
document._data[_field] is not None for _field in fields_to_fetch
646+
):
647+
return document # Data is already fetched
625648
return await sync_to_async(
626-
field.document_type.objects()
627-
.no_dereference()
628-
.only(*(set(list(_type._meta.required_fields) + queried_fields)))
629-
.get
649+
field.document_type.objects().no_dereference().only(*fields_to_fetch).get
630650
)(pk=getattr(root, field.name or field.db_name))
631651
return None
632652

0 commit comments

Comments
 (0)