简体   繁体   English

Flask-SQLAlchemy导入/上下文问题

[英]Flask-SQLAlchemy import/context issue

I want to structure my Flask app something like: 我想构建我的Flask应用,例如:

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

apps.members is a Flask Blueprint. apps.members是一个烧瓶蓝图。

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

But if I try and import that model into my Blueprint app, I get the dreaded RuntimeError: working outside of request context . 但是,如果我尝试将该模型导入到我的Blueprint应用程序中,则会得到可怕的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, eg: 相对导入可能有效,但是它们很丑陋,并且具有自己的上下文问题,例如:

from ...site import app

# ValueError: Attempted relative import beyond toplevel package

The flask_sqlalchemy module does not have to be initialized with the app right away - you can do this instead: flask_sqlalchemy模块不必立即使用应用程序初始化-您可以执行以下操作:

# apps.members.models
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

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

And then in your application setup you can call init_app : 然后在您的应用程序设置中,您可以调用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. 这样可以避免周期性导入。

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. 只需将db变量导入到每个模型模块中即可。

Example

# 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)

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.) 注意:这是一些功能的草图 -显然,您可以做很多事来create_app开发工作(使用create_app模式,在某些文件夹中自动注册蓝图等)。

an original app.py : https://flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart/ 原来app.py: https://flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart/

...

app = flask.Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = flask.ext.sqlalchemy.SQLAlchemy(app)

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
...

class Computer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
...

# Create the database tables.
db.create_all()

...

# start the flask loop
app.run()

I just splitted one app.py to app.py and model.py without using Blueprint. 我只是将一个app.py拆分为app.py和model.py而不使用Blueprint。 In that case, the above answer dosen't work. 在这种情况下,以上答案无效。 A line code is needed to work. 需要行代码才能工作。

before : 之前

db.init_app(app)

after : 之后

db.app = app
db.init_app(app)

And, the following link is very useful. 并且,以下链接非常有用。

http://piotr.banaszkiewicz.org/blog/2012/06/29/flask-sqlalchemy-init_app/ http://piotr.banaszkiewicz.org/blog/2012/06/29/flask-sqlalchemy-init_app/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM