Skip to content

Commit e07076d

Browse files
committed
Isolated Graphene SQLAlchemy in new package
0 parents  commit e07076d

28 files changed

+1646
-0
lines changed

.coveragerc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[run]
2+
omit = */tests/*

.gitignore

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Created by https://www.gitignore.io
2+
3+
### Python ###
4+
# Byte-compiled / optimized / DLL files
5+
__pycache__/
6+
*.py[cod]
7+
8+
# C extensions
9+
*.so
10+
11+
# Distribution / packaging
12+
.Python
13+
env/
14+
build/
15+
develop-eggs/
16+
dist/
17+
downloads/
18+
eggs/
19+
.eggs/
20+
lib/
21+
lib64/
22+
parts/
23+
sdist/
24+
var/
25+
*.egg-info/
26+
.installed.cfg
27+
*.egg
28+
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.coverage
43+
.coverage.*
44+
.cache
45+
nosetests.xml
46+
coverage.xml
47+
*,cover
48+
49+
# Translations
50+
*.mo
51+
*.pot
52+
53+
# Django stuff:
54+
*.log
55+
56+
# Sphinx documentation
57+
docs/_build/
58+
59+
# PyBuilder
60+
target/
61+
62+
# PyCharm
63+
.idea
64+
65+
# Databases
66+
*.sqlite3
67+
.vscode

.travis.yml

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
language: python
2+
sudo: false
3+
python:
4+
- 2.7
5+
- 3.4
6+
- 3.5
7+
- pypy
8+
before_install:
9+
- |
10+
if [ "$TRAVIS_PYTHON_VERSION" = "pypy" ]; then
11+
export PYENV_ROOT="$HOME/.pyenv"
12+
if [ -f "$PYENV_ROOT/bin/pyenv" ]; then
13+
cd "$PYENV_ROOT" && git pull
14+
else
15+
rm -rf "$PYENV_ROOT" && git clone --depth 1 https://github.com/yyuu/pyenv.git "$PYENV_ROOT"
16+
fi
17+
export PYPY_VERSION="4.0.1"
18+
"$PYENV_ROOT/bin/pyenv" install "pypy-$PYPY_VERSION"
19+
virtualenv --python="$PYENV_ROOT/versions/pypy-$PYPY_VERSION/bin/python" "$HOME/virtualenvs/pypy-$PYPY_VERSION"
20+
source "$HOME/virtualenvs/pypy-$PYPY_VERSION/bin/activate"
21+
fi
22+
install:
23+
- |
24+
if [ "$TEST_TYPE" = build ]; then
25+
pip install pytest==3.0.2 pytest-cov pytest-benchmark coveralls six mock
26+
pip install -e .
27+
python setup.py develop
28+
elif [ "$TEST_TYPE" = lint ]; then
29+
pip install flake8
30+
fi
31+
script:
32+
- |
33+
if [ "$TEST_TYPE" = lint ]; then
34+
echo "Checking Python code lint."
35+
flake8 graphene_sqlalchemy
36+
exit
37+
elif [ "$TEST_TYPE" = build ]; then
38+
py.test --cov=graphene_sqlalchemy graphene_sqlalchemy examples
39+
fi
40+
after_success:
41+
- |
42+
if [ "$TEST_TYPE" = build ]; then
43+
coveralls
44+
fi
45+
env:
46+
matrix:
47+
- TEST_TYPE=build
48+
matrix:
49+
fast_finish: true
50+
include:
51+
- python: '2.7'
52+
env: TEST_TYPE=lint

README.md

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
You are in the `next` unreleased version of Graphene-sqlalchemy (`1.0.dev`).
2+
Please read [UPGRADE-v1.0.md](https://github.com/graphql-python/graphene/blob/master/UPGRADE-v1.0.md) to learn how to upgrade.
3+
4+
---
5+
6+
# ![Graphene Logo](http://graphene-python.org/favicon.png) Graphene-SQLAlchemy [![Build Status](https://travis-ci.org/graphql-python/graphene-sqlalchemy.svg?branch=master)](https://travis-ci.org/graphql-python/graphene-sqlalchemy) [![PyPI version](https://badge.fury.io/py/graphene-sqlalchemy.svg)](https://badge.fury.io/py/graphene-sqlalchemy) [![Coverage Status](https://coveralls.io/repos/graphql-python/graphene-sqlalchemy/badge.svg?branch=master&service=github)](https://coveralls.io/github/graphql-python/graphene-sqlalchemy?branch=master)
7+
8+
9+
A [SQLAlchemy](http://www.sqlalchemy.org/) integration for [Graphene](http://graphene-python.org/).
10+
11+
## Installation
12+
13+
For instaling graphene, just run this command in your shell
14+
15+
```bash
16+
pip install "graphene-sqlalchemy>=1.0.dev"
17+
```
18+
19+
## Examples
20+
21+
Here is a simple SQLAlchemy model:
22+
23+
```python
24+
from sqlalchemy import Column, Integer, String
25+
from sqlalchemy.orm import backref, relationship
26+
27+
from sqlalchemy.ext.declarative import declarative_base
28+
29+
Base = declarative_base()
30+
31+
class UserModel(Base):
32+
__tablename__ = 'department'
33+
id = Column(Integer, primary_key=True)
34+
name = Column(String)
35+
last_name = Column(String)
36+
```
37+
38+
To create a GraphQL schema for it you simply have to write the following:
39+
40+
```python
41+
from graphene_sqlalchemy import SQLAlchemyObjectType
42+
43+
class User(SQLAlchemyObjectType):
44+
class Meta:
45+
model = UserModel
46+
47+
class Query(graphene.ObjectType):
48+
users = graphene.List(User)
49+
50+
def resolve_users(self, args, context, info):
51+
query = User.get_query(context) # SQLAlchemy query
52+
return query.all()
53+
54+
schema = graphene.Schema(query=QueryRoot)
55+
```
56+
57+
Then you can simply query the schema:
58+
59+
```python
60+
query = '''
61+
query {
62+
users {
63+
name,
64+
lastName
65+
}
66+
}
67+
'''
68+
result = schema.execute(query, context_value={'session': db_session})
69+
```
70+
71+
To learn more check out the following [examples](examples/):
72+
73+
* **Full example**: [Flask SQLAlchemy example](examples/flask_sqlalchemy)
74+
75+
76+
## Contributing
77+
78+
After cloning this repo, ensure dependencies are installed by running:
79+
80+
```sh
81+
python setup.py install
82+
```
83+
84+
After developing, the full test suite can be evaluated by running:
85+
86+
```sh
87+
python setup.py test # Use --pytest-args="-v -s" for verbose mode
88+
```

bin/autolinter

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
3+
# Install the required scripts with
4+
# pip install autoflake autopep8 isort
5+
autoflake ./examples/ ./graphene_sqlalchemy/ -r --remove-unused-variables --remove-all-unused-imports --in-place
6+
autopep8 ./examples/ ./graphene_sqlalchemy/ -r --in-place --experimental --aggressive --max-line-length 120
7+
isort -rc ./examples/ ./graphene_sqlalchemy/

bin/convert_documentation

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
3+
pandoc README.md --from markdown --to rst -s -o README.rst

examples/flask_sqlalchemy/README.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Example Flask+SQLAlchemy Project
2+
================================
3+
4+
This example project demos integration between Graphene, Flask and SQLAlchemy.
5+
The project contains two models, one named `Department` and another
6+
named `Employee`.
7+
8+
Getting started
9+
---------------
10+
11+
First you'll need to get the source of the project. Do this by cloning the
12+
whole Graphene repository:
13+
14+
```bash
15+
# Get the example project code
16+
git clone https://github.com/graphql-python/graphene.git
17+
cd graphene/examples/flask_sqlalchemy
18+
```
19+
20+
It is good idea (but not required) to create a virtual environment
21+
for this project. We'll do this using
22+
[virtualenv](http://docs.python-guide.org/en/latest/dev/virtualenvs/)
23+
to keep things simple,
24+
but you may also find something like
25+
[virtualenvwrapper](https://virtualenvwrapper.readthedocs.org/en/latest/)
26+
to be useful:
27+
28+
```bash
29+
# Create a virtualenv in which we can install the dependencies
30+
virtualenv env
31+
source env/bin/activate
32+
```
33+
34+
Now we can install our dependencies:
35+
36+
```bash
37+
pip install -r requirements.txt
38+
```
39+
40+
Now the following command will setup the database, and start the server:
41+
42+
```bash
43+
./app.py
44+
45+
```
46+
47+
48+
Now head on over to
49+
[http://127.0.0.1:5000/graphiql](http://127.0.0.1:5000/graphiql)
50+
and run some queries!

examples/flask_sqlalchemy/__init__.py

Whitespace-only changes.

examples/flask_sqlalchemy/app.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from flask import Flask
2+
3+
from database import db_session, init_db
4+
from flask_graphql import GraphQLView
5+
from schema import schema
6+
7+
app = Flask(__name__)
8+
app.debug = True
9+
10+
default_query = '''
11+
{
12+
allEmployees {
13+
edges {
14+
node {
15+
id,
16+
name,
17+
department {
18+
id,
19+
name
20+
},
21+
role {
22+
id,
23+
name
24+
}
25+
}
26+
}
27+
}
28+
}'''.strip()
29+
30+
31+
app.add_url_rule('/graphql', view_func=GraphQLView.as_view('graphql', schema=schema, graphiql=True))
32+
33+
34+
@app.teardown_appcontext
35+
def shutdown_session(exception=None):
36+
db_session.remove()
37+
38+
if __name__ == '__main__':
39+
init_db()
40+
app.run()

examples/flask_sqlalchemy/database.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from sqlalchemy import create_engine
2+
from sqlalchemy.ext.declarative import declarative_base
3+
from sqlalchemy.orm import scoped_session, sessionmaker
4+
5+
engine = create_engine('sqlite:///database.sqlite3', convert_unicode=True)
6+
db_session = scoped_session(sessionmaker(autocommit=False,
7+
autoflush=False,
8+
bind=engine))
9+
Base = declarative_base()
10+
Base.query = db_session.query_property()
11+
12+
13+
def init_db():
14+
# import all modules here that might define models so that
15+
# they will be registered properly on the metadata. Otherwise
16+
# you will have to import them first before calling init_db()
17+
from models import Department, Employee, Role
18+
Base.metadata.drop_all(bind=engine)
19+
Base.metadata.create_all(bind=engine)
20+
21+
# Create the fixtures
22+
engineering = Department(name='Engineering')
23+
db_session.add(engineering)
24+
hr = Department(name='Human Resources')
25+
db_session.add(hr)
26+
27+
manager = Role(name='manager')
28+
db_session.add(manager)
29+
engineer = Role(name='engineer')
30+
db_session.add(engineer)
31+
32+
peter = Employee(name='Peter', department=engineering, role=engineer)
33+
db_session.add(peter)
34+
roy = Employee(name='Roy', department=engineering, role=engineer)
35+
db_session.add(roy)
36+
tracy = Employee(name='Tracy', department=hr, role=manager)
37+
db_session.add(tracy)
38+
db_session.commit()

examples/flask_sqlalchemy/models.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, func
2+
from sqlalchemy.orm import backref, relationship
3+
4+
from database import Base
5+
6+
7+
class Department(Base):
8+
__tablename__ = 'department'
9+
id = Column(Integer, primary_key=True)
10+
name = Column(String)
11+
12+
13+
class Role(Base):
14+
__tablename__ = 'roles'
15+
role_id = Column(Integer, primary_key=True)
16+
name = Column(String)
17+
18+
19+
class Employee(Base):
20+
__tablename__ = 'employee'
21+
id = Column(Integer, primary_key=True)
22+
name = Column(String)
23+
# Use default=func.now() to set the default hiring time
24+
# of an Employee to be the current time when an
25+
# Employee record was created
26+
hired_on = Column(DateTime, default=func.now())
27+
department_id = Column(Integer, ForeignKey('department.id'))
28+
role_id = Column(Integer, ForeignKey('roles.role_id'))
29+
# Use cascade='delete,all' to propagate the deletion of a Department onto its Employees
30+
department = relationship(
31+
Department,
32+
backref=backref('employees',
33+
uselist=True,
34+
cascade='delete,all'))
35+
role = relationship(
36+
Role,
37+
backref=backref('roles',
38+
uselist=True,
39+
cascade='delete,all'))

0 commit comments

Comments
 (0)