如何将Flask模型从app.py中拆分出来而又不传递数据库对象? [英] How do I split Flask models out of app.py without passing db object all over?
问题描述
我想使用烧瓶迁移,并查看他们的示例:
I'd like to use Flask-Migrate and am looking at their example:
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()
作为一个简单的播放示例,它的效果很好,但是我不仅有一个模型,而且我不想在此脚本和定义我的应用程序代码的模型中都定义模型.因此,我想将它们放入一个我可以在两者之间共享的模型文件中.
This works great as a simple play example, but I have more than a single model and I don't want to define the models in both this script and the one that defines my application code. Thus, I want to pull them into a model file that I can share between the two.
我试图通过将User
类放入models.py
然后从那里导入User来做到这一点.不幸的是,这引发了NameError: name 'db' is not defined
.
I attempting to do this, by placing the User
class into a models.py
and then importing User from there. Unfortunately, that throws a NameError: name 'db' is not defined
.
我的问题是:
- 我是否需要在
models.py
中使用db = SQLAlchemy(app)
,如果可以,我的迁移脚本和flask应用程序本身都可以使用它吗? - 如果我不能(或不应该)将其放入
models.py
,如何在不将db
全部传递给自己的文件中使用模型?
- Do I need to use
db = SQLAlchemy(app)
in mymodels.py
, and if so will this be available in both my migration script and the flask application itself? - If I can't (or shouldn't) put it in
models.py
, how do I utilize my models in their own file without passingdb
all over?
推荐答案
将这么小的应用程序划分为模块很棘手,因为您发现很多情况下,您创建的两个模块需要相互导入,从而形成循环依赖性.
Partitioning such a small application into modules is tricky, because you find a lot of cases where the two modules that you create need to mutually import each other, creating circular dependencies.
我建议您研究如何使用应用程序工厂功能和延迟所有扩展的初始化来正确构造更大的应用程序.我的书中精选的 Flasky 应用就是一个示例应用.
I recommend that you look at how you can structure a larger application properly, using an app factory function and delayed initialization of all extensions. An example application that does this is the Flasky app featured in my book.
总而言之,可以将应用程序分为两部分,您只需要注意放置导入语句的位置.在下面的示例中,我决定将db
实例和User
模型的创建移到models.py文件中.
All that said, it is possible to separate the application into two parts, you just need to be careful with where you place the import statements. In the example below, I decided to move the creation of the db
instance and the User
model into a models.py file.
这是主要应用程序的模块:
Here is the main application's module:
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:
And here is 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
和其他导入一起移至文件顶部,则此代码将中断.
Here the main module will create app
, and only then will import models.py. When models.py tries to import app
from the main module, it has already been created. If you move from models import db
to the top of the file with the other imports this code breaks.
这篇关于如何将Flask模型从app.py中拆分出来而又不传递数据库对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!