summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-04-11 06:03:38 +0000
committerCoprDistGit <infra@openeuler.org>2023-04-11 06:03:38 +0000
commitd79e2029b557887abb0506277790cfc849768aa6 (patch)
treef93b54c47a3c3ceaacaafb5c33a8d50cc2c3175f
parentc013d7d6fa793ddd83a97c981a2502b4660a3844 (diff)
automatic import of python-graphene-django-optimizer
-rw-r--r--.gitignore1
-rw-r--r--python-graphene-django-optimizer.spec711
-rw-r--r--sources1
3 files changed, 713 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..ae62aae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/graphene-django-optimizer-0.9.1.tar.gz
diff --git a/python-graphene-django-optimizer.spec b/python-graphene-django-optimizer.spec
new file mode 100644
index 0000000..7f2db31
--- /dev/null
+++ b/python-graphene-django-optimizer.spec
@@ -0,0 +1,711 @@
+%global _empty_manifest_terminate_build 0
+Name: python-graphene-django-optimizer
+Version: 0.9.1
+Release: 1
+Summary: Optimize database access inside graphene queries.
+License: MIT
+URL: https://github.com/tfoxy/graphene-django-optimizer
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/96/00/361d61157e8e3abe70abf0d12c994adbee50acb60a790bddc3c05ce6fb9f/graphene-django-optimizer-0.9.1.tar.gz
+BuildArch: noarch
+
+
+%description
+# graphene-django-optimizer
+
+[![build status](https://img.shields.io/travis/tfoxy/graphene-django-optimizer.svg)](https://travis-ci.com/github/tfoxy/graphene-django-optimizer)
+[![coverage](https://img.shields.io/codecov/c/github/tfoxy/graphene-django-optimizer.svg)](https://codecov.io/gh/tfoxy/graphene-django-optimizer)
+[![PyPI version](https://img.shields.io/pypi/v/graphene-django-optimizer.svg)](https://pypi.org/project/graphene-django-optimizer/)
+![python version](https://img.shields.io/pypi/pyversions/graphene-django-optimizer.svg)
+![django version](https://img.shields.io/pypi/djversions/graphene-django-optimizer.svg)
+
+Optimize queries executed by [graphene-django](https://github.com/graphql-python/graphene-django) automatically, using [`select_related`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#select-related), [`prefetch_related`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#prefetch-related) and [`only`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#only) methods of Django QuerySet.
+
+
+
+## Install
+
+```bash
+pip install graphene-django-optimizer
+```
+
+*Note: If you are using Graphene V2, please install version `0.8`. v0.9 and forward will support only Graphene V3*
+
+## Usage
+
+Having the following schema based on [the tutorial of graphene-django](http://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/#hello-graphql-schema-and-object-types) (notice the use of `gql_optimizer`)
+
+```py
+# cookbook/ingredients/schema.py
+import graphene
+
+from graphene_django.types import DjangoObjectType
+import graphene_django_optimizer as gql_optimizer
+
+from cookbook.ingredients.models import Category, Ingredient
+
+
+class CategoryType(DjangoObjectType):
+ class Meta:
+ model = Category
+
+
+class IngredientType(DjangoObjectType):
+ class Meta:
+ model = Ingredient
+
+
+class Query(graphene.ObjectType):
+ all_categories = graphene.List(CategoryType)
+ all_ingredients = graphene.List(IngredientType)
+
+ def resolve_all_categories(root, info):
+ return gql_optimizer.query(Category.objects.all(), info)
+
+ def resolve_all_ingredients(root, info):
+ return gql_optimizer.query(Ingredient.objects.all(), info)
+```
+
+
+We will show some graphql queries and the queryset that will be executed.
+
+Fetching all the ingredients with the related category:
+
+```graphql
+{
+ allIngredients {
+ id
+ name
+ category {
+ id
+ name
+ }
+ }
+}
+```
+
+```py
+# optimized queryset:
+ingredients = (
+ Ingredient.objects
+ .select_related('category')
+ .only('id', 'name', 'category__id', 'category__name')
+)
+```
+
+Fetching all the categories with the related ingredients:
+
+```graphql
+{
+ allCategories {
+ id
+ name
+ ingredients {
+ id
+ name
+ }
+ }
+}
+```
+
+```py
+# optimized queryset:
+categories = (
+ Category.objects
+ .only('id', 'name')
+ .prefetch_related(Prefetch(
+ 'ingredients',
+ queryset=Ingredient.objects.only('id', 'name'),
+ ))
+)
+```
+
+
+## Advanced usage
+
+Sometimes we need to have a custom resolver function. In those cases, the field can't be auto optimized.
+So we need to use `gql_optimizer.resolver_hints` decorator to indicate the optimizations.
+
+If the resolver returns a model field, we can use the `model_field` argument:
+
+```py
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class ItemType(gql_optimizer.OptimizedDjangoObjectType):
+ product = graphene.Field('ProductType')
+
+ @gql_optimizer.resolver_hints(
+ model_field='product',
+ )
+ def resolve_product(root, info):
+ # check if user have permission for seeing the product
+ if info.context.user.is_anonymous():
+ return None
+ return root.product
+```
+
+This will automatically optimize any subfield of `product`.
+
+Now, if the resolver uses related fields, you can use the `select_related` argument:
+
+```py
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class ItemType(gql_optimizer.OptimizedDjangoObjectType):
+ name = graphene.String()
+
+ @gql_optimizer.resolver_hints(
+ select_related=('product', 'shipping'),
+ only=('product__name', 'shipping__name'),
+ )
+ def resolve_name(root, info):
+ return '{} {}'.format(root.product.name, root.shipping.name)
+```
+
+Notice the usage of the type `OptimizedDjangoObjectType`, which enables
+optimization of any single node queries.
+
+Finally, if your field has an argument for filtering results,
+you can use the `prefetch_related` argument with a function
+that returns a `Prefetch` instance as the value.
+
+```py
+from django.db.models import Prefetch
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class CartType(gql_optimizer.OptimizedDjangoObjectType):
+ items = graphene.List(
+ 'ItemType',
+ product_id=graphene.ID(),
+ )
+
+ @gql_optimizer.resolver_hints(
+ prefetch_related=lambda info, product_id: Prefetch(
+ 'items',
+ queryset=gql_optimizer.query(Item.objects.filter(product_id=product_id), info),
+ to_attr='gql_product_id_' + product_id,
+ ),
+ )
+ def resolve_items(root, info, product_id):
+ return getattr(root, 'gql_product_id_' + product_id)
+```
+
+With these hints, any field can be optimized.
+
+
+### Optimize with non model fields
+
+Sometimes we need to have a custom non model fields. In those cases, the optimizer would not optimize with the Django `.only()` method.
+So if we still want to optimize with the `.only()` method, we need to use `disable_abort_only` option:
+
+```py
+
+class IngredientType(gql_optimizer.OptimizedDjangoObjectType):
+ calculated_calories = graphene.String()
+
+ class Meta:
+ model = Ingredient
+
+ def resolve_calculated_calories(root, info):
+ return get_calories_for_ingredient(root.id)
+
+
+class Query(object):
+ all_ingredients = graphene.List(IngredientType)
+
+ def resolve_all_ingredients(root, info):
+ return gql_optimizer.query(Ingredient.objects.all(), info, disable_abort_only=True)
+```
+
+
+
+
+%package -n python3-graphene-django-optimizer
+Summary: Optimize database access inside graphene queries.
+Provides: python-graphene-django-optimizer
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-graphene-django-optimizer
+# graphene-django-optimizer
+
+[![build status](https://img.shields.io/travis/tfoxy/graphene-django-optimizer.svg)](https://travis-ci.com/github/tfoxy/graphene-django-optimizer)
+[![coverage](https://img.shields.io/codecov/c/github/tfoxy/graphene-django-optimizer.svg)](https://codecov.io/gh/tfoxy/graphene-django-optimizer)
+[![PyPI version](https://img.shields.io/pypi/v/graphene-django-optimizer.svg)](https://pypi.org/project/graphene-django-optimizer/)
+![python version](https://img.shields.io/pypi/pyversions/graphene-django-optimizer.svg)
+![django version](https://img.shields.io/pypi/djversions/graphene-django-optimizer.svg)
+
+Optimize queries executed by [graphene-django](https://github.com/graphql-python/graphene-django) automatically, using [`select_related`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#select-related), [`prefetch_related`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#prefetch-related) and [`only`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#only) methods of Django QuerySet.
+
+
+
+## Install
+
+```bash
+pip install graphene-django-optimizer
+```
+
+*Note: If you are using Graphene V2, please install version `0.8`. v0.9 and forward will support only Graphene V3*
+
+## Usage
+
+Having the following schema based on [the tutorial of graphene-django](http://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/#hello-graphql-schema-and-object-types) (notice the use of `gql_optimizer`)
+
+```py
+# cookbook/ingredients/schema.py
+import graphene
+
+from graphene_django.types import DjangoObjectType
+import graphene_django_optimizer as gql_optimizer
+
+from cookbook.ingredients.models import Category, Ingredient
+
+
+class CategoryType(DjangoObjectType):
+ class Meta:
+ model = Category
+
+
+class IngredientType(DjangoObjectType):
+ class Meta:
+ model = Ingredient
+
+
+class Query(graphene.ObjectType):
+ all_categories = graphene.List(CategoryType)
+ all_ingredients = graphene.List(IngredientType)
+
+ def resolve_all_categories(root, info):
+ return gql_optimizer.query(Category.objects.all(), info)
+
+ def resolve_all_ingredients(root, info):
+ return gql_optimizer.query(Ingredient.objects.all(), info)
+```
+
+
+We will show some graphql queries and the queryset that will be executed.
+
+Fetching all the ingredients with the related category:
+
+```graphql
+{
+ allIngredients {
+ id
+ name
+ category {
+ id
+ name
+ }
+ }
+}
+```
+
+```py
+# optimized queryset:
+ingredients = (
+ Ingredient.objects
+ .select_related('category')
+ .only('id', 'name', 'category__id', 'category__name')
+)
+```
+
+Fetching all the categories with the related ingredients:
+
+```graphql
+{
+ allCategories {
+ id
+ name
+ ingredients {
+ id
+ name
+ }
+ }
+}
+```
+
+```py
+# optimized queryset:
+categories = (
+ Category.objects
+ .only('id', 'name')
+ .prefetch_related(Prefetch(
+ 'ingredients',
+ queryset=Ingredient.objects.only('id', 'name'),
+ ))
+)
+```
+
+
+## Advanced usage
+
+Sometimes we need to have a custom resolver function. In those cases, the field can't be auto optimized.
+So we need to use `gql_optimizer.resolver_hints` decorator to indicate the optimizations.
+
+If the resolver returns a model field, we can use the `model_field` argument:
+
+```py
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class ItemType(gql_optimizer.OptimizedDjangoObjectType):
+ product = graphene.Field('ProductType')
+
+ @gql_optimizer.resolver_hints(
+ model_field='product',
+ )
+ def resolve_product(root, info):
+ # check if user have permission for seeing the product
+ if info.context.user.is_anonymous():
+ return None
+ return root.product
+```
+
+This will automatically optimize any subfield of `product`.
+
+Now, if the resolver uses related fields, you can use the `select_related` argument:
+
+```py
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class ItemType(gql_optimizer.OptimizedDjangoObjectType):
+ name = graphene.String()
+
+ @gql_optimizer.resolver_hints(
+ select_related=('product', 'shipping'),
+ only=('product__name', 'shipping__name'),
+ )
+ def resolve_name(root, info):
+ return '{} {}'.format(root.product.name, root.shipping.name)
+```
+
+Notice the usage of the type `OptimizedDjangoObjectType`, which enables
+optimization of any single node queries.
+
+Finally, if your field has an argument for filtering results,
+you can use the `prefetch_related` argument with a function
+that returns a `Prefetch` instance as the value.
+
+```py
+from django.db.models import Prefetch
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class CartType(gql_optimizer.OptimizedDjangoObjectType):
+ items = graphene.List(
+ 'ItemType',
+ product_id=graphene.ID(),
+ )
+
+ @gql_optimizer.resolver_hints(
+ prefetch_related=lambda info, product_id: Prefetch(
+ 'items',
+ queryset=gql_optimizer.query(Item.objects.filter(product_id=product_id), info),
+ to_attr='gql_product_id_' + product_id,
+ ),
+ )
+ def resolve_items(root, info, product_id):
+ return getattr(root, 'gql_product_id_' + product_id)
+```
+
+With these hints, any field can be optimized.
+
+
+### Optimize with non model fields
+
+Sometimes we need to have a custom non model fields. In those cases, the optimizer would not optimize with the Django `.only()` method.
+So if we still want to optimize with the `.only()` method, we need to use `disable_abort_only` option:
+
+```py
+
+class IngredientType(gql_optimizer.OptimizedDjangoObjectType):
+ calculated_calories = graphene.String()
+
+ class Meta:
+ model = Ingredient
+
+ def resolve_calculated_calories(root, info):
+ return get_calories_for_ingredient(root.id)
+
+
+class Query(object):
+ all_ingredients = graphene.List(IngredientType)
+
+ def resolve_all_ingredients(root, info):
+ return gql_optimizer.query(Ingredient.objects.all(), info, disable_abort_only=True)
+```
+
+
+
+
+%package help
+Summary: Development documents and examples for graphene-django-optimizer
+Provides: python3-graphene-django-optimizer-doc
+%description help
+# graphene-django-optimizer
+
+[![build status](https://img.shields.io/travis/tfoxy/graphene-django-optimizer.svg)](https://travis-ci.com/github/tfoxy/graphene-django-optimizer)
+[![coverage](https://img.shields.io/codecov/c/github/tfoxy/graphene-django-optimizer.svg)](https://codecov.io/gh/tfoxy/graphene-django-optimizer)
+[![PyPI version](https://img.shields.io/pypi/v/graphene-django-optimizer.svg)](https://pypi.org/project/graphene-django-optimizer/)
+![python version](https://img.shields.io/pypi/pyversions/graphene-django-optimizer.svg)
+![django version](https://img.shields.io/pypi/djversions/graphene-django-optimizer.svg)
+
+Optimize queries executed by [graphene-django](https://github.com/graphql-python/graphene-django) automatically, using [`select_related`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#select-related), [`prefetch_related`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#prefetch-related) and [`only`](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#only) methods of Django QuerySet.
+
+
+
+## Install
+
+```bash
+pip install graphene-django-optimizer
+```
+
+*Note: If you are using Graphene V2, please install version `0.8`. v0.9 and forward will support only Graphene V3*
+
+## Usage
+
+Having the following schema based on [the tutorial of graphene-django](http://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/#hello-graphql-schema-and-object-types) (notice the use of `gql_optimizer`)
+
+```py
+# cookbook/ingredients/schema.py
+import graphene
+
+from graphene_django.types import DjangoObjectType
+import graphene_django_optimizer as gql_optimizer
+
+from cookbook.ingredients.models import Category, Ingredient
+
+
+class CategoryType(DjangoObjectType):
+ class Meta:
+ model = Category
+
+
+class IngredientType(DjangoObjectType):
+ class Meta:
+ model = Ingredient
+
+
+class Query(graphene.ObjectType):
+ all_categories = graphene.List(CategoryType)
+ all_ingredients = graphene.List(IngredientType)
+
+ def resolve_all_categories(root, info):
+ return gql_optimizer.query(Category.objects.all(), info)
+
+ def resolve_all_ingredients(root, info):
+ return gql_optimizer.query(Ingredient.objects.all(), info)
+```
+
+
+We will show some graphql queries and the queryset that will be executed.
+
+Fetching all the ingredients with the related category:
+
+```graphql
+{
+ allIngredients {
+ id
+ name
+ category {
+ id
+ name
+ }
+ }
+}
+```
+
+```py
+# optimized queryset:
+ingredients = (
+ Ingredient.objects
+ .select_related('category')
+ .only('id', 'name', 'category__id', 'category__name')
+)
+```
+
+Fetching all the categories with the related ingredients:
+
+```graphql
+{
+ allCategories {
+ id
+ name
+ ingredients {
+ id
+ name
+ }
+ }
+}
+```
+
+```py
+# optimized queryset:
+categories = (
+ Category.objects
+ .only('id', 'name')
+ .prefetch_related(Prefetch(
+ 'ingredients',
+ queryset=Ingredient.objects.only('id', 'name'),
+ ))
+)
+```
+
+
+## Advanced usage
+
+Sometimes we need to have a custom resolver function. In those cases, the field can't be auto optimized.
+So we need to use `gql_optimizer.resolver_hints` decorator to indicate the optimizations.
+
+If the resolver returns a model field, we can use the `model_field` argument:
+
+```py
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class ItemType(gql_optimizer.OptimizedDjangoObjectType):
+ product = graphene.Field('ProductType')
+
+ @gql_optimizer.resolver_hints(
+ model_field='product',
+ )
+ def resolve_product(root, info):
+ # check if user have permission for seeing the product
+ if info.context.user.is_anonymous():
+ return None
+ return root.product
+```
+
+This will automatically optimize any subfield of `product`.
+
+Now, if the resolver uses related fields, you can use the `select_related` argument:
+
+```py
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class ItemType(gql_optimizer.OptimizedDjangoObjectType):
+ name = graphene.String()
+
+ @gql_optimizer.resolver_hints(
+ select_related=('product', 'shipping'),
+ only=('product__name', 'shipping__name'),
+ )
+ def resolve_name(root, info):
+ return '{} {}'.format(root.product.name, root.shipping.name)
+```
+
+Notice the usage of the type `OptimizedDjangoObjectType`, which enables
+optimization of any single node queries.
+
+Finally, if your field has an argument for filtering results,
+you can use the `prefetch_related` argument with a function
+that returns a `Prefetch` instance as the value.
+
+```py
+from django.db.models import Prefetch
+import graphene
+import graphene_django_optimizer as gql_optimizer
+
+
+class CartType(gql_optimizer.OptimizedDjangoObjectType):
+ items = graphene.List(
+ 'ItemType',
+ product_id=graphene.ID(),
+ )
+
+ @gql_optimizer.resolver_hints(
+ prefetch_related=lambda info, product_id: Prefetch(
+ 'items',
+ queryset=gql_optimizer.query(Item.objects.filter(product_id=product_id), info),
+ to_attr='gql_product_id_' + product_id,
+ ),
+ )
+ def resolve_items(root, info, product_id):
+ return getattr(root, 'gql_product_id_' + product_id)
+```
+
+With these hints, any field can be optimized.
+
+
+### Optimize with non model fields
+
+Sometimes we need to have a custom non model fields. In those cases, the optimizer would not optimize with the Django `.only()` method.
+So if we still want to optimize with the `.only()` method, we need to use `disable_abort_only` option:
+
+```py
+
+class IngredientType(gql_optimizer.OptimizedDjangoObjectType):
+ calculated_calories = graphene.String()
+
+ class Meta:
+ model = Ingredient
+
+ def resolve_calculated_calories(root, info):
+ return get_calories_for_ingredient(root.id)
+
+
+class Query(object):
+ all_ingredients = graphene.List(IngredientType)
+
+ def resolve_all_ingredients(root, info):
+ return gql_optimizer.query(Ingredient.objects.all(), info, disable_abort_only=True)
+```
+
+
+
+
+%prep
+%autosetup -n graphene-django-optimizer-0.9.1
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-graphene-django-optimizer -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Tue Apr 11 2023 Python_Bot <Python_Bot@openeuler.org> - 0.9.1-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..84237ae
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+221b5de22824e20efbc44e473951cf3b graphene-django-optimizer-0.9.1.tar.gz