Flask-SQLAlchemy 导入/上下文问题 [英] Flask-SQLAlchemy import/context issue

查看:29
本文介绍了Flask-SQLAlchemy 导入/上下文问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想像这样构建我的 Flask 应用程序:

I want to structure my Flask app something like:

./site.py
./apps/members/__init__.py
./apps/members/models.py

apps.members 是一个 Flask 蓝图.

apps.members is a Flask Blueprint.

现在,为了创建模型类,我需要掌握应用程序,例如:

Now, in order to create the model classes I need to have a hold of the app, something like:

# apps.members.models
from flask import current_app
from flaskext.sqlalchemy import SQLAlchemy

db = SQLAlchemy(current_app)

class Member(db.Model):
    # fields here
    pass

但是如果我尝试将该模型导入我的蓝图应用程序,我会遇到可怕的RuntimeError:在请求上下文之外工作.如何在此处正确获取我的应用程序?相对导入可能有效,但它们非常丑陋并且有自己的上下文问题,例如:

But if I try and import that model into my Blueprint app, I get the dreaded RuntimeError: working outside of request context. How can I get a hold of my app correctly here? Relative imports might work but they're pretty ugly and have their own context issues, e.g:

from ...site import app

# ValueError: Attempted relative import beyond toplevel package

推荐答案

flask_sqlalchemy 模块不必立即使用应用程序初始化 - 您可以改为这样做:

The flask_sqlalchemy module does not have to be initialized with the app right away - you can do this instead:

# apps.members.models
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Member(db.Model):
    # fields here
    pass

然后在您的应用程序设置中,您可以调用 init_app:

And then in your application setup you can call init_app:

# apps.application.py
from flask import Flask
from apps.members.models import db

app = Flask(__name__)
# later on
db.init_app(app)

这样您就可以避免周期性导入.

This way you can avoid cyclical imports.

这种模式不需要将所有模型放在一个文件中.只需将 db 变量导入您的每个模型模块.

This pattern does not necessitate the you place all of your models in one file. Simply import the db variable into each of your model modules.

# apps.shared.models
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

# apps.members.models
from apps.shared.models import db

class Member(db.Model):
    # TODO: Implement this.
    pass

# apps.reporting.members
from flask import render_template
from apps.members.models import Member

def report_on_members():
    # TODO: Actually use arguments
    members = Member.filter(1==1).all()
    return render_template("report.html", members=members)

# apps.reporting.routes
from flask import Blueprint
from apps.reporting.members import report_on_members

reporting = Blueprint("reporting", __name__)

reporting.route("/member-report", methods=["GET","POST"])(report_on_members)

# apps.application
from flask import Flask
from apps.shared import db
from apps.reporting.routes import reporting

app = Flask(__name__)
db.init_app(app)
app.register_blueprint(reporting)

注意:这是一个草图它给你的一些力量——显然你可以做更多的事情来使开发甚至更容易(使用 create_app 模式,在某些文件夹中自动注册蓝图等)

Note: this is a sketch of some of the power this gives you - there is obviously quite a bit more that you can do to make development even easier (using a create_app pattern, auto-registering blueprints in certain folders, etc.)

这篇关于Flask-SQLAlchemy 导入/上下文问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆