使用Graphene Python构建GraphQL x Flask x SQLAlchemy Server


本文的内容

  • 本文总结了如何使用Graphene Python构建GraphQL x Flask x SQLAlchemy Server。

什么是GraphQL(目前)

  • Facebook开源查询语言
  • 作为REST的替代品,它引起了人们的注意。
  • 您可以轻松描述客户端和服务器之间的数据交换。
  • 以JSON格式返回查询结果

参考
* https://qiita.com/syu_chan_1005/items/3350f1d12c17a77e98c7
* https://vitalify.jp/app-lab/20171006-graphql/
* https://tukumemo.com/graphql/

什么是石墨烯

  • 适用于Python的GraphQL框架(可能适用于JavaScript)

    • https://graphene-python.org/

执行环境

  • MacOS Mojave 10.14.1
  • Python 3.6.5
  • 烧瓶1.0.2
  • sqlite 3.24.0

直到你移动

  • 根据http://docs.graphene-python.org/projects/sqlalchemy/zh-CN/latest/tutorial/的内容进行翻译

Shell脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## プロジェクト用のディレクトリを作成
mkdir flask_sqlalchemy
cd flask_sqlalchemy

## virtualenv 環境の作成と読み込み
virtualenv env
source env/bin/activate  # On Windows use `env\Scripts\activate`

## SQLAlchemy と graphene_sqlalchemy の pip install
pip install SQLAlchemy
pip install graphene_sqlalchemy

## Flask と Flask-GraphQL のインストール
pip install Flask
pip install Flask-GraphQL

型号定义

flask_sqlalchemy / models.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# flask_sqlalchemy/models.py
from sqlalchemy import *
from sqlalchemy.orm import (scoped_session, sessionmaker, relationship,
                            backref)
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()
# We will need this for querying
Base.query = db_session.query_property()


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)
    hired_on = Column(DateTime, default=func.now())
    department_id = Column(Integer, ForeignKey('department.id'))
    department = relationship(
        Department,
        backref=backref('employees',
                        uselist=True,
                        cascade='delete,all'))

创建架构

GraphQL将对象表示为图形结构,而不是熟悉的层次结构。

此示例提供了通过all_employees列出所有雇员的功能以及通过节点获取特定节点的功能。

创建

flask_sqlalchemy/schema.py并进行如下编辑:

flask_sqlalchemy / schema.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# flask_sqlalchemy/schema.py
import graphene
from graphene import relay
from graphene_sqlalchemy import SQLAlchemyObjectType, SQLAlchemyConnectionField
from models import db_session, Department as DepartmentModel, Employee as EmployeeModel


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


class DepartmentConnection(relay.Connection):
    class Meta:
        node = Department


class Employee(SQLAlchemyObjectType):
    class Meta:
        model = EmployeeModel
        interfaces = (relay.Node, )


class EmployeeConnection(relay.Connection):
    class Meta:
        node = Employee


class Query(graphene.ObjectType):
    node = relay.Node.Field()
    # Allows sorting over multiple columns, by default over the primary key
    all_employees = SQLAlchemyConnectionField(EmployeeConnection)
    # Disable sorting over this field
    all_departments = SQLAlchemyConnectionField(DepartmentConnection, sort=None)

schema = graphene.Schema(query=Query)

在Flask

上创建GraphQL环境

与RESTful API不同,GraphQL仅由一个URL访问。

使用

Flask创建一个服务器,该服务器公开/graphql下的GraphQL模式和一个名为GraphiQL的接口,以方便查询执行。

Flask-GraphQL库可以帮助您实现此功能。

flask_sqlalchemy / app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# flask_sqlalchemy/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()

尝试创建数据

使用

$ python3打开控制台。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> from models import engine, db_session, Base, Department, Employee
>>> Base.metadata.create_all(bind=engine)

>>> # Fill the tables with some data
>>> engineering = Department(name='Engineering')
>>> db_session.add(engineering)
>>> hr = Department(name='Human Resources')
>>> db_session.add(hr)

>>> peter = Employee(name='Peter', department=engineering)
>>> db_session.add(peter)
>>> roy = Employee(name='Roy', department=engineering)
>>> db_session.add(roy)
>>> tracy = Employee(name='Tracy', department=hr)
>>> db_session.add(tracy)
>>> db_session.commit()

GraphQL操作测试

现在您可以开始了。让我们从命令行启动Server并检查操作。

1
2
$ python3 ./app.py
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

启动后,尝试访问http://本地主机:5000 / graphql。

image.png

在左侧输入查询以检查操作。

询问

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  allEmployees {
    edges {
      node {
        id
        name
        department {
          name
        }
      }
    }
  }
}

image.png

现在您可以看到对查询的响应。

这就是本文的全部内容。
当您要构建一个简单的GraphQL DB Server时,它似乎非常有用。

如果不起作用,请在Github存储库中找到一个示例,因此请尝试一下。

已经很长时间了,但是感谢您阅读??

奖金

似乎有针对MongoDB的教程
* https://graphene-mongo.readthedocs.io/en/latest/tutorial.html