【问题标题】:Integrate graphql into flask blueprint将 graphql 集成到烧瓶蓝图中
【发布时间】:2018-09-26 19:47:13
【问题描述】:

我目前正在尝试将 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

问题出在两个教程中,建议在模型文件中创建基础和引擎,我也这样做了,但我需要使用 current_app 读取配置文件以获取 URI 以创建引擎。但实际上,因为它发生在flask初始化中,所以还没有请求上下文,所以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()

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

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

请您推荐最佳做法来设置它吗?

非常感谢!

【问题讨论】:

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


    【解决方案1】:

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

    app/__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)
    

    那么你需要在你的模型中做的就是:

    app/models.py

    Base = declarative_base()
    
    class Model1_Model(Base):
    

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

    【讨论】:

    • 感谢 mhaps。我正在使用这种完全相同的方式来初始化数据库。受到您的回答的启发并找到了一个好的解决方案
    【解决方案2】:

    尝试在

    中启动蓝图
        app.__init__
    

    我和你有同样的时间,因为

        __name__ 
    

    应该是应用

    【讨论】:

    • 谢谢。我试过这个,也想不出办法。我正在使用 init.py 中的 create_app() 函数来初始化所有组件。
    • 没有什么比你得到它更好的了
    【解决方案3】:

    终于想通了不用current_app怎么办:

    1. 在config.py中,多数据库绑定方式:

      SQLALCHEMY_BINDS = {
      'db1': DB1_URI,
      'db2': DB2_URI
      }
      
    2. 在models.py中,这样做

      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 切换,则可能需要不同的解决方案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-16
      • 2012-09-27
      • 2015-07-16
      • 1970-01-01
      • 2021-02-08
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多