Интегрируйте graphql в проект flask

В настоящее время я пытаюсь интегрировать GraphQL (используя графен и flask_graphql) в свое приложение Flask. Пробовал несколько туториалов от здесь и здесь. Но, похоже, в моей ситуации ничего не работает. В настоящее время мой проект похож на этот

-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 для создания движка. Но на самом деле, поскольку это происходит при инициализации фляги, пока нет контекста запроса, поэтому 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 есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
701
3

Ответы 3

Попробуйте запустить Blueprint в

    app.__init__

У меня такое же время, как и у тебя, потому что

    __name__ 

должно быть приложение

Спасибо. Я пробовал это и тоже не мог придумать способ. Я использую функцию create_app () в в этом.py для инициализации всего компонента.

capaneus 17.04.2018 11:01

Нет ничего лучше, чем ты понимаешь

JYFelt 18.04.2018 08:14

Я бы предложил использовать инициализацию фляги для определения соединения с БД. Таким образом, вы можете использовать внутреннюю реализацию 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):

Затем в определении маршрута вместо использования db_seesion из вашей модели внутри вашего контекста вы можете ссылаться на db Flask, например context = {'session': db.session}), который вы создали в функции create_app().

спасибо, возможно. Я использую точно такой же способ инициализации db. Вдохновленный вашим ответом и нашедший хорошее решение

capaneus 19.04.2018 02:32

Наконец разобрался, как это сделать без использования 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'
    

    Таким образом, модель сможет получить доступ к надлежащему uri базы данных без current_app, но если app_context переключится, возможно, потребуется другое решение.

Другие вопросы по теме