使用Flask应用工厂模式时,如何将模型定义在单独文件中?
在Flask应用工厂模式下单独定义模型的正确姿势
嘿,我懂你现在的需求——用应用工厂模式搭Flask应用,想把模型代码从__init__.py里抽出来单独存放,避免核心文件臃肿不堪对吧?这其实是构建中大型Flask应用的标准操作,我给你一步步拆解怎么做:
第一步:调整__init__.py里的应用工厂和DB初始化
首先要改掉原来直接把app传给SQLAlchemy的写法,因为应用工厂模式下我们会创建多个app实例(比如开发用、测试用),所以得用延迟初始化的方式创建DB对象:
from flask import Flask from flask_sqlalchemy import SQLAlchemy # 先创建db实例,暂时不绑定app db = SQLAlchemy() def create_app(test_config=None): app = Flask(__name__, instance_relative_config=True) app.config.from_mapping( SECRET_KEY='dev', SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:@localhost/database', SQLALCHEMY_TRACK_MODIFICATIONS=False # 建议加上,关闭不必要的性能消耗 ) if test_config is None: app.config.from_pyfile('config.py', silent=True) else: app.config.from_mapping(test_config) # 把db和当前app实例绑定 db.init_app(app) # 关键:绑定db后再导入模型,避免循环导入 from . import models # 可选:添加CLI命令用来创建表(替代直接在代码里调用db.create_all()) @app.cli.command("create-tables") def create_tables(): with app.app_context(): db.create_all() # 这里可以继续注册蓝图、初始化其他扩展等 # from .views import main_bp # app.register_blueprint(main_bp) return app
第二步:创建单独的模型文件(或文件夹)
在应用目录下新建一个models.py文件(如果模型多,也可以建models文件夹,里面分多个文件),然后在里面导入我们刚才创建的db对象来定义模型:
# models.py from . import db class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) def __repr__(self): return f'<User {self.username}>'
如果模型数量多,推荐用文件夹结构:
- 新建
models文件夹,里面创建__init__.py、user.py、post.py等 - 在
models/__init__.py里导入所有模型:
# models/__init__.py from .user import User from .post import Post
- 单个模型文件(比如
user.py)里这样写:
# models/user.py from .. import db class User(db.Model): # 字段定义...
第三步:解决核心问题——循环导入
为什么要在create_app里绑定db之后再导入模型?因为如果模型文件里先导入db,而db又依赖app,直接导入会导致循环引用错误。把模型导入放在db.init_app(app)之后,就能确保db已经完成初始化,不会报错。
第四步:创建数据库表
不要在模型文件里直接调用db.create_all(),因为此时没有Flask应用上下文。可以用我们刚才定义的CLI命令:
- 先设置环境变量(Windows用
set,Linux/macOS用export):
export FLASK_APP=你的应用名 export FLASK_ENV=development
- 运行命令创建表:
flask create-tables
如果用Flask-Migrate做数据库迁移,只需要在create_app里初始化Migrate即可:
from flask_migrate import Migrate # 在create_app函数里,db.init_app(app)之后添加: migrate = Migrate(app, db)
这样迁移脚本就能自动识别所有模型啦。
内容的提问来源于stack exchange,提问作者swarnava112
相关产品推荐
相关产品推荐

