diff --git a/examples/flask_sqlalchemy/README.md b/examples/flask_sqlalchemy/README.md new file mode 100644 index 00000000..0af0d4b0 --- /dev/null +++ b/examples/flask_sqlalchemy/README.md @@ -0,0 +1,50 @@ +Cookbook Example Django Project +=============================== + +This example project demos integration between Graphene, Flask and SQLAlchemy. +The project contains two models, one named `Department` and another +named `Employee`. + +Getting started +--------------- + +First you'll need to get the source of the project. Do this by cloning the +whole Graphene repository: + +```bash +# Get the example project code +git clone https://github.com/graphql-python/graphene.git +cd graphene/examples/cookbook +``` + +It is good idea (but not required) to create a virtual environment +for this project. We'll do this using +[virtualenv](http://docs.python-guide.org/en/latest/dev/virtualenvs/) +to keep things simple, +but you may also find something like +[virtualenvwrapper](https://virtualenvwrapper.readthedocs.org/en/latest/) +to be useful: + +```bash +# Create a virtualenv in which we can install the dependencies +virtualenv env +source env/bin/activate +``` + +Now we can install our dependencies: + +```bash +pip install -r requirements.txt +``` + +Now the following command will setup the database, and start the server: + +```bash +./app.py + +``` + + +Now head on over to +[http://127.0.0.1:5000/](http://127.0.0.1:5000/) +and run some queries! diff --git a/examples/flask_sqlalchemy/__init__.py b/examples/flask_sqlalchemy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/examples/flask_sqlalchemy/app.py b/examples/flask_sqlalchemy/app.py new file mode 100644 index 00000000..7188bfbf --- /dev/null +++ b/examples/flask_sqlalchemy/app.py @@ -0,0 +1,22 @@ +import json +from flask import Flask +from database import db_session, init_db + +from schema import schema, Department + +app = Flask(__name__) + + +@app.route('/') +def hello_world(): + query = '{node(id:"%s"){name, employees { edges { node {name} } } } }' % Department.global_id(1) + return json.dumps(schema.execute(query).data) + + +@app.teardown_appcontext +def shutdown_session(exception=None): + db_session.remove() + +if __name__ == '__main__': + init_db() + app.run() diff --git a/examples/flask_sqlalchemy/database.py b/examples/flask_sqlalchemy/database.py new file mode 100644 index 00000000..c4a520c7 --- /dev/null +++ b/examples/flask_sqlalchemy/database.py @@ -0,0 +1,27 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import scoped_session, sessionmaker +from sqlalchemy.ext.declarative import declarative_base + +engine = create_engine('sqlite:///database.sqlite3', convert_unicode=True) +db_session = scoped_session(sessionmaker(autocommit=False, + autoflush=False, + bind=engine)) +Base = declarative_base() +Base.query = db_session.query_property() + + +def init_db(): + # import all modules here that might define models so that + # they will be registered properly on the metadata. Otherwise + # you will have to import them first before calling init_db() + from models import Department, Employee + Base.metadata.drop_all(bind=engine) + Base.metadata.create_all(bind=engine) + + department = Department(name='Informatics') + db_session.add(department) + + db_session.add(department) + employee = Employee(name='Peter', department=department) + db_session.add(employee) + db_session.commit() diff --git a/examples/flask_sqlalchemy/models.py b/examples/flask_sqlalchemy/models.py new file mode 100644 index 00000000..7561bb29 --- /dev/null +++ b/examples/flask_sqlalchemy/models.py @@ -0,0 +1,26 @@ +from database import Base +from sqlalchemy import Column, DateTime, String, Integer, ForeignKey, func +from sqlalchemy.orm import relationship, backref + + +class Department(Base): + __tablename__ = 'department' + id = Column(Integer, primary_key=True) + name = Column(String) + + +class Employee(Base): + __tablename__ = 'employee' + id = Column(Integer, primary_key=True) + name = Column(String) + # Use default=func.now() to set the default hiring time + # of an Employee to be the current time when an + # Employee record was created + hired_on = Column(DateTime, default=func.now()) + department_id = Column(Integer, ForeignKey('department.id')) + # Use cascade='delete,all' to propagate the deletion of a Department onto its Employees + department = relationship( + Department, + backref=backref('employees', + uselist=True, + cascade='delete,all')) diff --git a/examples/flask_sqlalchemy/requirements.txt b/examples/flask_sqlalchemy/requirements.txt new file mode 100644 index 00000000..88ba848f --- /dev/null +++ b/examples/flask_sqlalchemy/requirements.txt @@ -0,0 +1,3 @@ +graphene[sqlalchemy] +SQLAlchemy==1.0.11 +Flask==0.10.1 diff --git a/examples/flask_sqlalchemy/schema.py b/examples/flask_sqlalchemy/schema.py new file mode 100644 index 00000000..8e167f77 --- /dev/null +++ b/examples/flask_sqlalchemy/schema.py @@ -0,0 +1,26 @@ +import graphene +from graphene import relay +from graphene.contrib.sqlalchemy import SQLAlchemyNode +from models import Department as DepartmentModel, Employee as EmployeeModel + +from database import db_session + +schema = graphene.Schema(session=db_session) + + +@schema.register +class Department(SQLAlchemyNode): + class Meta: + model = DepartmentModel + + +@schema.register +class Employee(SQLAlchemyNode): + class Meta: + model = EmployeeModel + + +class Query(graphene.ObjectType): + node = relay.NodeField(Department, Employee) + +schema.query = Query