From c42b2c10f962bb253b3b2c2986ae9543e373aeaa Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Tue, 6 Sep 2022 00:48:00 +0200 Subject: [PATCH 1/5] Use Graphene Datoader in graphene>=3.1.1 Signed-off-by: Erik Wrede --- graphene_sqlalchemy/batching.py | 21 +++++++++++++++++++-- graphene_sqlalchemy/utils.py | 7 +++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/graphene_sqlalchemy/batching.py b/graphene_sqlalchemy/batching.py index 85cc8855..119cc019 100644 --- a/graphene_sqlalchemy/batching.py +++ b/graphene_sqlalchemy/batching.py @@ -1,13 +1,30 @@ +"""The dataloader uses "select in loading" strategy to load related entities.""" +from typing import Any + import aiodataloader import sqlalchemy from sqlalchemy.orm import Session, strategies from sqlalchemy.orm.query import QueryContext -from .utils import is_sqlalchemy_version_less_than +from .utils import (is_graphene_version_less_than, + is_sqlalchemy_version_less_than) -def get_batch_resolver(relationship_prop): +def get_data_loader_impl() -> Any: + """Graphene >= 3.1.1 ships a copy of aiodataloader with minor fixes. To preserve backward-compatibility, + aiodataloader is used in conjunction with older versions of graphene""" + if is_graphene_version_less_than("3.1.1"): + from aiodataloader import DataLoader + else: + from graphene.utils.dataloader import DataLoader + + return DataLoader + +DataLoader = get_data_loader_impl() + + +def get_batch_resolver(relationship_prop): # Cache this across `batch_load_fn` calls # This is so SQL string generation is cached under-the-hood via `bakery` selectin_loader = strategies.SelectInLoader(relationship_prop, (('lazy', 'selectin'),)) diff --git a/graphene_sqlalchemy/utils.py b/graphene_sqlalchemy/utils.py index f6ee9b62..27abe336 100644 --- a/graphene_sqlalchemy/utils.py +++ b/graphene_sqlalchemy/utils.py @@ -156,6 +156,11 @@ def is_sqlalchemy_version_less_than(version_string): return pkg_resources.get_distribution('SQLAlchemy').parsed_version < pkg_resources.parse_version(version_string) +def is_graphene_version_less_than(version_string): + """Check the installed graphene version""" + return pkg_resources.get_distribution('graphene').parsed_version < pkg_resources.parse_version(version_string) + + class singledispatchbymatchfunction: """ Inspired by @singledispatch, this is a variant that works using a matcher function @@ -197,6 +202,7 @@ def safe_isinstance_checker(arg): return isinstance(arg, cls) except TypeError: pass + return safe_isinstance_checker @@ -210,5 +216,6 @@ def registry_sqlalchemy_model_from_str(model_name: str) -> Optional[Any]: class DummyImport: """The dummy module returns 'object' for a query for any member""" + def __getattr__(self, name): return object From b6aaad16d5d6b5d47edca3c856c89ee7d5032a75 Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Wed, 7 Sep 2022 13:59:35 +0200 Subject: [PATCH 2/5] Added nocov to conditional import --- graphene_sqlalchemy/batching.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene_sqlalchemy/batching.py b/graphene_sqlalchemy/batching.py index 119cc019..8d54a23f 100644 --- a/graphene_sqlalchemy/batching.py +++ b/graphene_sqlalchemy/batching.py @@ -10,7 +10,7 @@ is_sqlalchemy_version_less_than) -def get_data_loader_impl() -> Any: +def get_data_loader_impl() -> Any: # pragma: no cover """Graphene >= 3.1.1 ships a copy of aiodataloader with minor fixes. To preserve backward-compatibility, aiodataloader is used in conjunction with older versions of graphene""" if is_graphene_version_less_than("3.1.1"): From 5b106792626ea703225d360ac1253b5d83f91843 Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Wed, 7 Sep 2022 14:00:54 +0200 Subject: [PATCH 3/5] Don't require coverage for pkg_resource functions --- graphene_sqlalchemy/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphene_sqlalchemy/utils.py b/graphene_sqlalchemy/utils.py index 27abe336..e86eecfa 100644 --- a/graphene_sqlalchemy/utils.py +++ b/graphene_sqlalchemy/utils.py @@ -151,12 +151,12 @@ def sort_argument_for_model(cls, has_default=True): return Argument(List(enum), default_value=enum.default) -def is_sqlalchemy_version_less_than(version_string): +def is_sqlalchemy_version_less_than(version_string): # pragma: no cover """Check the installed SQLAlchemy version""" return pkg_resources.get_distribution('SQLAlchemy').parsed_version < pkg_resources.parse_version(version_string) -def is_graphene_version_less_than(version_string): +def is_graphene_version_less_than(version_string): # pragma: no cover """Check the installed graphene version""" return pkg_resources.get_distribution('graphene').parsed_version < pkg_resources.parse_version(version_string) From fbe5c43019f43c7fc17b919b04a9fd496de9b68d Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Wed, 7 Sep 2022 14:02:10 +0200 Subject: [PATCH 4/5] Fix Lint --- graphene_sqlalchemy/batching.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene_sqlalchemy/batching.py b/graphene_sqlalchemy/batching.py index 8d54a23f..e56b1e4c 100644 --- a/graphene_sqlalchemy/batching.py +++ b/graphene_sqlalchemy/batching.py @@ -10,7 +10,7 @@ is_sqlalchemy_version_less_than) -def get_data_loader_impl() -> Any: # pragma: no cover +def get_data_loader_impl() -> Any: # pragma: no cover """Graphene >= 3.1.1 ships a copy of aiodataloader with minor fixes. To preserve backward-compatibility, aiodataloader is used in conjunction with older versions of graphene""" if is_graphene_version_less_than("3.1.1"): From 9b505029c66dc3e2a331bf88e4a0f7766e9c61bf Mon Sep 17 00:00:00 2001 From: Erik Wrede Date: Wed, 7 Sep 2022 14:03:23 +0200 Subject: [PATCH 5/5] Fix Lint in utils --- graphene_sqlalchemy/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphene_sqlalchemy/utils.py b/graphene_sqlalchemy/utils.py index e86eecfa..27117c0c 100644 --- a/graphene_sqlalchemy/utils.py +++ b/graphene_sqlalchemy/utils.py @@ -151,12 +151,12 @@ def sort_argument_for_model(cls, has_default=True): return Argument(List(enum), default_value=enum.default) -def is_sqlalchemy_version_less_than(version_string): # pragma: no cover +def is_sqlalchemy_version_less_than(version_string): # pragma: no cover """Check the installed SQLAlchemy version""" return pkg_resources.get_distribution('SQLAlchemy').parsed_version < pkg_resources.parse_version(version_string) -def is_graphene_version_less_than(version_string): # pragma: no cover +def is_graphene_version_less_than(version_string): # pragma: no cover """Check the installed graphene version""" return pkg_resources.get_distribution('graphene').parsed_version < pkg_resources.parse_version(version_string)