Python SQLAlchemy导入/上下文问题

Python SQLAlchemy导入/上下文问题,python,flask,flask-sqlalchemy,Python,Flask,Flask Sqlalchemy,我想构建我的Flask应用程序,如下所示: ./site.py ./apps/members/__init__.py ./apps/members/models.py # apps.members.models from flask import current_app from flaskext.sqlalchemy import SQLAlchemy db = SQLAlchemy(current_app) class Member(db.Model): # fields he

我想构建我的Flask应用程序,如下所示:

./site.py
./apps/members/__init__.py
./apps/members/models.py
# apps.members.models
from flask import current_app
from flaskext.sqlalchemy import SQLAlchemy

db = SQLAlchemy(current_app)

class Member(db.Model):
    # fields here
    pass
apps.members
是一个烧瓶蓝图

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

./site.py
./apps/members/__init__.py
./apps/members/models.py
# apps.members.models
from flask import current_app
from flaskext.sqlalchemy import SQLAlchemy

db = SQLAlchemy(current_app)

class Member(db.Model):
    # fields here
    pass
但是,如果我尝试将该模型导入Blueprint应用程序,就会出现可怕的
运行时错误:在请求上下文之外工作。我怎样才能在这里正确掌握我的应用程序?相对导入可能有效,但它们非常丑陋,并且有自己的上下文问题,例如:

from ...site import app

# ValueError: Attempted relative import beyond toplevel package

flask\u sqlalchemy
模块不必立即用应用程序初始化-您可以这样做:

# apps.members.models
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Member(db.Model):
    # fields here
    pass
然后在应用程序设置中,您可以调用
init\u app

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

app = Flask(__name__)
# later on
db.init_app(app)
这样可以避免周期性导入

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

例子


注意:这是它给你的一些力量的简图-显然,你可以做更多的事情来让开发变得更容易(使用
创建应用程序
模式,在某些文件夹中自动注册蓝图,等等)

原始的app.py

我只是在不使用Blueprint的情况下将一个app.py拆分为app.py和model.py。在这种情况下,上述答案不起作用。需要行代码才能工作

之前

db.init_app(app)
db.app = app
db.init_app(app)
之后

db.init_app(app)
db.app = app
db.init_app(app)
下面的链接非常有用


您能多次这样做吗?例如,如果我有多个models.py文件?@BradWright-如果您只为您拥有的每个数据库创建
db
实例,那么就更容易了。如果你有一个模型包,你可以把它放在
\uuu init\uuuu.py
中。无论您选择如何操作,只需将
db
变量从该位置导入到其他模型文件中,并正常使用即可。加载后,所有内容都会正确解析。您是否碰巧有一个指向以这种方式设置的项目的链接?@Mbrevda-您可以在这里看到此模式的示例
.ext.
命名空间已被弃用-最好从真实命名空间导入(
flask\u sqlalchemy
).
db.app=app
获取运行时错误,因为init_app未设置app+1
db.app=app
(后面是
db.init_app(app)
)是我缺少的一部分。在添加该行(结合Sean Vieira的回答)后,第一个链接已经过时,效果非常好。
db.init_app(app)
db.app = app
db.init_app(app)