SQLAlchemy + FLASK + Graphene Tutorial


Merhabalar , kısa süredir graphql ile ilgilenmekteyim. Graphql başta Facebook ve Netflix devlerin aktif olarak “veriye erişim/sorgulama modeli” olarak kullandığı mimari ortaya çıkarıldı. Yani bir veri tabanı sorgulama dili değil !

FB’un Graphql kullanmasındaki en büyük etkenlerden birisi de tek sorguda kullanıcı hakkında bütün bilgileri çekebilmek. Future-proof düşündüğünüzde projelerinizde graphql kullanmanız kulağa mantıklı geliyor. Python ve Go dilinde Graphql hakkında yararlı linkleri yazının sonunda paylaşacağım. Şimdi projemizin gereksinimlerine geçelim.

Kurulum

//proje klasörünü oluşturalım
mkdir graphql
cd graphql
//Paket bağımlılıklarımız için virtualenv oluşturalım
virtualenv env
source env/bin/activate
//sqlalchemy ve graphene destekleyen sqlalchemy paketleri
sudo pip3 install SQLAlchemy
sudo pip3 install graphene_sqlalchemy

//flask ve Grapql destekleyen flask paketleri
pip install Flask
pip install Flask-GraphQL
pip install pymysql //mysql kullanacaksanız

Modellerimizi Oluşturalım

SQLAlchemy için modellerimizi oluşturmaya geldik. Daha öncesinde sqlalchemy ve flask kullananlar için tanıdık gelicektir. Bizim modellerimizde kullanıcılarımız ve bunların bölümleri olsun.

#graphql/models.py
from sqlalchemy import *
from sqlalchemy.orm import (scoped_session, sessionmaker, relationship, backref)
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql+pymysql://root:@localhost/tutorial', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

class Department(Base):
__tablename__ = 'department'
id = Column(Integer, primary_key=True)
name = Column(String)

class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)
hired_on = Column(DateTime, default=func.now())
department_id = Column(Integer, ForeignKey('department.id'))
department = relationship( Department, backref=backref('users', uselist=True, cascade='delete,all'))

Burada create_engine olarak mysql kullanılmıştır. sqllite veya başka bir database kullanmak isterseniz Sqlalchemy Engines inceleyebilirsiniz.

Schema

GraphQL, nesnelerinizi alıştığınız daha hiyerarşik bir yapı olmaktan ziyade bir grafik yapısı olarak dünyaya sunar. Bu gösterimi yaratmak için Graphene’in grafikte görünecek her nesne türü hakkında bilgi sahibi olması gerekir.

Bu grafikte, tüm erişimin başladığı bir kök türü de vardır. Bu, aşağıdaki Sorgu sınıfıdır. Bu örnekte, tüm kullanıcıları all_users aracılığıyla listeleme olanağı ve düğüm aracılığıyla belirli bir düğüm edinme olanağı sağlarız.

# graphql/schema.py
import graphene
from graphene import relay
from graphene_sqlalchemy import SQLAlchemyObjectType, SQLAlchemyConnectionField
from models import db_session, Department as DepartmentModel, User as UserModel

class Department(SQLAlchemyObjectType):
class Meta:
model = DepartmentModel
interfaces = (relay.Node, )

class User(SQLAlchemyObjectType):
class Meta:
model = UserModel
interfaces = (relay.Node, )

class Query(graphene.ObjectType):
node = relay.Node.Field()
all_users = SQLAlchemyConnectionField(User)
schema = graphene.Schema(query=Query)

Vee Flask-GraphiQL

# graphql/app.py
from flask import Flask
from flask_graphql import GraphQLView
from models import db_session
from schema import schema, Department
app = Flask(__name__)
app.debug = True
app.add_url_rule(
'/graphql',
view_func=GraphQLView.as_view(
'graphql',
schema=schema,
graphiql=True # for having the GraphiQL interface
)
)
@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
if __name__ == '__main__':
app.run()

Veritabanımıza Veri Ekleyelim

Python terminaline girdikten sonra aşağıdaki verileri eklememiz hem veritabanını oluşturur hemde verileri ekler.

from models import engine, db_session, Base, Department, User
Base.metadata.create_all(bind=engine)
engineering = Department(name='Engineering')
db_session.add(engineering)
roy = User(name='Roy', department=engineering)
db_session.add(roy)
kity = User(name='Kity', department=engineering)
db_session.add(kity)
db_session.commit()

RUN

python ./app.py

çalıştırdıktan sonra Graphiql Ide ile karşılaşacaksınız. Query olarak veya Ide içerisine bütün kullanıcıları listelemek için aşağıdaki queryi yazabilirsiniz.

{
allUsers {
edges {
node {
id
name
department {
name
}
}
}
}
}

Okuduğunuz için Teşekkürler.

Projenin source kodu :

Yararlı Linkler :

Graphene 
Graphql Learn 
How to Graphql 
Netflix Falcor 
FB Graphql Think 
Graphiql IDE

Go Graphql