Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
erikwrede authored May 5, 2022
2 parents c821bce + a47dbb3 commit 957df3d
Show file tree
Hide file tree
Showing 27 changed files with 858 additions and 271 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: 🚀 Deploy to PyPI

on:
push:
tags:
- '*'

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Build wheel and source tarball
run: |
pip install wheel
python setup.py sdist bdist_wheel
- name: Publish a Python distribution to PyPI
uses: pypa/gh-action-pypi-publish@v1.1.0
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
22 changes: 22 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Lint

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- name: Run lint 💅
run: tox
env:
TOXENV: flake8
38 changes: 38 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Tests

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
strategy:
max-parallel: 10
matrix:
sql-alchemy: ["1.2", "1.3", "1.4"]
python-version: ["3.6", "3.7", "3.8", "3.9"]

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox tox-gh-actions
- name: Test with tox
run: tox
env:
SQLALCHEMY: ${{ matrix.sql-alchemy }}
TOXENV: ${{ matrix.toxenv }}
- name: Upload coverage.xml
if: ${{ matrix.sql-alchemy == '1.4' && matrix.python-version == '3.9' }}
uses: actions/upload-artifact@v2
with:
name: graphene-sqlalchemy-coverage
path: coverage.xml
if-no-files-found: error
- name: Upload coverage.xml to codecov
if: ${{ matrix.sql-alchemy == '1.4' && matrix.python-version == '3.9' }}
uses: codecov/codecov-action@v1
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,6 @@ target/
# Databases
*.sqlite3
.vscode

# mypy cache
.mypy_cache/
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
default_language_version:
python: python3.7
repos:
- repo: git://github.com/pre-commit/pre-commit-hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: c8bad492e1b1d65d9126dba3fe3bd49a5a52b9d6 # v2.1.0
hooks:
- id: check-merge-conflict
Expand All @@ -11,15 +11,15 @@ repos:
exclude: ^docs/.*$
- id: trailing-whitespace
exclude: README.md
- repo: git://github.com/PyCQA/flake8
- repo: https://github.com/PyCQA/flake8
rev: 88caf5ac484f5c09aedc02167c59c66ff0af0068 # 3.7.7
hooks:
- id: flake8
- repo: git://github.com/asottile/seed-isort-config
- repo: https://github.com/asottile/seed-isort-config
rev: v1.7.0
hooks:
- id: seed-isort-config
- repo: git://github.com/pre-commit/mirrors-isort
- repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.4
hooks:
- id: isort
47 changes: 0 additions & 47 deletions .travis.yml

This file was deleted.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ A [SQLAlchemy](http://www.sqlalchemy.org/) integration for [Graphene](http://gra

## Installation

For instaling graphene, just run this command in your shell
For installing Graphene, just run this command in your shell.

```bash
pip install "graphene-sqlalchemy>=2.0"
Expand All @@ -34,7 +34,7 @@ class UserModel(Base):
last_name = Column(String)
```

To create a GraphQL schema for it you simply have to write the following:
To create a GraphQL schema for it, you simply have to write the following:

```python
import graphene
Expand Down
2 changes: 1 addition & 1 deletion graphene_sqlalchemy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from .fields import SQLAlchemyConnectionField
from .utils import get_query, get_session

__version__ = "2.3.0"
__version__ = "3.0.0b1"

__all__ = [
"__version__",
Expand Down
49 changes: 33 additions & 16 deletions graphene_sqlalchemy/batching.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import aiodataloader
import sqlalchemy
from promise import dataloader, promise
from sqlalchemy.orm import Session, strategies
from sqlalchemy.orm.query import QueryContext

from .utils import is_sqlalchemy_version_less_than


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'),))

class RelationshipLoader(dataloader.DataLoader):
class RelationshipLoader(aiodataloader.DataLoader):
cache = False

def batch_load_fn(self, parents): # pylint: disable=method-hidden
async def batch_load_fn(self, parents):
"""
Batch loads the relationships of all the parents as one SQL statement.
Expand Down Expand Up @@ -52,21 +54,36 @@ def batch_load_fn(self, parents): # pylint: disable=method-hidden
states = [(sqlalchemy.inspect(parent), True) for parent in parents]

# For our purposes, the query_context will only used to get the session
query_context = QueryContext(session.query(parent_mapper.entity))

selectin_loader._load_for_path(
query_context,
parent_mapper._path_registry,
states,
None,
child_mapper,
)

return promise.Promise.resolve([getattr(parent, relationship_prop.key) for parent in parents])
query_context = None
if is_sqlalchemy_version_less_than('1.4'):
query_context = QueryContext(session.query(parent_mapper.entity))
else:
parent_mapper_query = session.query(parent_mapper.entity)
query_context = parent_mapper_query._compile_context()

if is_sqlalchemy_version_less_than('1.4'):
selectin_loader._load_for_path(
query_context,
parent_mapper._path_registry,
states,
None,
child_mapper
)
else:
selectin_loader._load_for_path(
query_context,
parent_mapper._path_registry,
states,
None,
child_mapper,
None
)

return [getattr(parent, relationship_prop.key) for parent in parents]

loader = RelationshipLoader()

def resolve(root, info, **args):
return loader.load(root)
async def resolve(root, info, **args):
return await loader.load(root)

return resolve
Loading

0 comments on commit 957df3d

Please sign in to comment.