如何将Flask模型从app.py中分离出来,而不将db对象到处传递?

2024-04-27 02:34:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用Flask-Migrate来看看他们的例子:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

db = SQLAlchemy(app)
migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))

if __name__ == '__main__':
    manager.run()

作为一个简单的示例,这很好,但是我有不止一个模型,我不想在这个脚本和定义我的应用程序代码的脚本中定义模型。因此,我想把它们拉到一个模型文件中,我可以在两者之间共享。

我试图这样做,将User类放入models.py中,然后从那里导入用户。不幸的是,这会抛出一个NameError: name 'db' is not defined

我的问题是:

  • 我是否需要在我的models.py中使用db = SQLAlchemy(app),如果需要,这在我的迁移脚本和flask应用程序本身中是否都可用?
  • 如果我不能(或者不应该)把它放在models.py中,我如何利用自己文件中的模型而不把db到处传递?

Tags: namefrompy模型import脚本appflask
2条回答

将这样一个小的应用程序划分成模块是很棘手的,因为您发现很多情况下,您创建的两个模块需要相互导入,从而创建循环依赖关系。

我建议您看看如何使用app factory函数和延迟初始化所有扩展来正确地构造更大的应用程序。这样做的一个示例应用程序是我的书中的Flasky应用程序。

尽管如此,将应用程序分为两部分是可能的,您只需小心将导入语句放在何处即可。在下面的示例中,我决定将db实例和User模型的创建移动到models.py文件中。

以下是主应用程序的模块:

from flask import Flask
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

from models import db  # <-- this needs to be placed after app is created
migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()

下面是models.py:

from __main__ import app
from flask.ext.sqlalchemy import SQLAlchemy

db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))

在这里,主模块将创建app,然后才导入models.py。当models.py试图从主模块导入app时,它已经被创建。如果将from models import db移动到文件的顶部,并使用其他导入,则此代码将中断。

这是一个主意。您可以创建一个包model,在该包中将类定义为单独的.py文件。例如,user.py包含User类。

__init__.py文件中,可以定义db变量。您还可以包含from user import User语句,这样就可以直接访问包外部的User对象。例如,可以使用import modelmodel包导入程序中的其他位置,然后使用model.User直接使用User类。

要直接在user.py中使用db变量,请使用from ..model import db,该变量导入__init__.py文件中定义的db变量。

相关问题 更多 >