将graphql集成到flask蓝图中

时间:2018-04-17 00:17:22

标签: python flask graphql flask-sqlalchemy graphene-python

我目前正在尝试将GraphQL(使用石墨烯和flask_graphql)集成到我的烧瓶应用中。尝试了herehere的一些教程。但似乎在我的情况下没有任何作用。 目前我的项目是这样的

-manage.py
  |app
     |__init__.py (create_app is here)
     |mod_graphql (this is folder)
         |__init__.py (blueprint created here)
         |models.py
         |schema.py
         |controller.py

问题出在这两个教程中,它建议在模型文件中创建Base和引擎,我做了同样的事情,但是我需要使用current_app读取配置文件来创建引擎的URI。但实际上,因为它发生在烧瓶初始化中,所以还没有请求上下文,所以current_app不存在。一切都失败了。 是否有可能帮我设置它?

以下是一些代码:

app/__init__.py
create_app():
    ...
    from .mod_graphql import bp_graph
    app.register_blueprint(bp_graph)
    ...

mod_graphql/__init__.py

from flask import Blueprint
bp_graph = Blueprint('graphql', __name__)
from . import controller
from . import models
from . import schema

mod_graphql/models.py

Base = declarative_base()
engine = create_engine(current_app.config.get('BASE_URI'), 
             convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base.query = db_session.query_property()

class Model1_Model(Base):
...

class Model2_Model(Base):
...

mod_graphql/schema.py

class Model1(SQLAlchemyObjectType):
    class Meta:
        model = Model1_Model
        interfaces = (relay.Node,)

class Model2(SQLAlchemyObjectType):
    class Meta:
        model = Model2_Model
        interfaces = (relay.Node,)

class Query(graphene.ObjectType):
    node = relay.Node.Field()
schema = graphene.Schema(query=Query, types=[Model1])


mod_graphql/controller.py

bp_graph.add_url_rule('/graphql',
                      view_func=GraphQLView.as_view('graphql',
                                                    schema=schema,
                                                    graphiql=True,
                                                    context={'session': 
                                                    db_session}))
@bp_graph.teardown_app_request()
def shutdown_session(exception=True):
    db_session.remove()

当我尝试启动服务器时,它会告诉我:

在应用程序上下文之外工作

你会推荐最好的做法来设置吗?

非常感谢!

3 个答案:

答案 0 :(得分:1)

我建议使用flask初始化来定义数据库连接。这样,您可以使用Flask的内部实现连接到数据库,而无需在您自己的

上定义它

应用程序/ __init__。PY

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    db.init_app(app)

然后你需要在你的模型中做的就是:

应用程序/ models.py

Base = declarative_base()

class Model1_Model(Base):

然后在您的路线定义中,而不是在您的上下文中使用模型中的db_seesion,您可以引用您在db函数中创建的context={'session': db.session}) create_app()之类的{{1}}

答案 1 :(得分:0)

尝试在

中启动蓝图
    app.__init__

我和你在同一时间,

    __name__ 

应该是app

答案 2 :(得分:0)

最后想出了如何在不使用current_app的情况下执行此操作:

    config.py中的
  1. 和多数据库绑定:

    SQLALCHEMY_BINDS = {
    'db1': DB1_URI,
    'db2': DB2_URI
    }
    
  2. models.py中的
  3. ,执行此操作

    engine = db.get_engine(bind='db1')
    metaData = MetaData()
    metaData.reflect(engine)
    Base = automap_base(metadata=MetaData)
    
    class Model1(Base):
        __tablename__ = 'db1_tablename'
    

    通过这种方式,模型将能够在没有current_app的情况下访问正确的数据库uri,但如果app_context切换,则可能需要不同的解决方案