如何在不传递db对象的情况下将Flask模型从app.py中分离出来?

时间:2015-12-15 05:41:24

标签: python flask flask-migrate

我想使用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

我的问题是:

  • 我是否需要在db = SQLAlchemy(app)中使用models.py,如果是这样,我的迁移脚本和刻录应用程序本身都可以使用它?
  • 如果我不能(或不应该)将其放入models.py,如何在不通过db的情况下在自己的文件中使用我的模型?

2 个答案:

答案 0 :(得分:17)

将这么小的应用程序分区到模块中是很棘手的,因为你发现很多情况下你创建的两个模块需要相互导入,创建循环依赖。

我建议您查看如何使用应用工厂函数和所有扩展的延迟初始化来正确构建更大的应用程序。执行此操作的示例应用程序是我的书中的Flasky应用程序。

所有这一切,可以将应用程序分成两部分,您只需要小心放置import语句的位置。在下面的示例中,我决定将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移动到文件顶部,则此代码会中断。

答案 1 :(得分:0)

这是一个想法。您可以创建一个包model,在其中将类定义为单个.py文件。例如,user.py包含User类。

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

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