Python中如何在Flask项目中使用多个文件保存models
请教 flask 怎么实现用多个文件保存 models。
初始化数据库的时候,如果所有的 models 都保存在同一个文件中就可以全部建表成功;如果放在不同的文件中,则只有一个文件中的能建表成功。
我现在使用的方法是在 db.py 中
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
在 models 文件中继承 db.Model 编写 model 类。
创建数据库命令:
db.drop_all()
db.create_all()
db.session.commit()
Python中如何在Flask项目中使用多个文件保存models
在实例化 flask app 之后,导入一下所有的 model 文件就好了呀~
在Flask项目里把models分到多个文件里,挺常见的需求,特别是项目大了以后。核心思路就是用SQLAlchemy的db对象,但别在每个文件里重复创建,而是从一个地方导入。下面给你个清晰的例子。
假设你的项目结构是这样的:
your_project/
├── app.py
├── models/
│ ├── __init__.py
│ ├── user.py
│ └── product.py
└── requirements.txt
1. 创建数据库实例和初始化文件 (models/__init__.py)
这是关键。在这里创建SQLAlchemy实例,以后所有model文件都从这里导入db。
# models/__init__.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
# 注意:这里先不导入各个model类
2. 定义各个Model (分文件)
每个文件定义自己的模型类,并从models包导入共享的db。
# models/user.py
from . import db # 从当前包的__init__.py导入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/product.py
from . import db
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
price = db.Column(db.Float)
def __repr__(self):
return f'<Product {self.name}>'
3. 在__init__.py中后导入模型 (解决循环导入)
现在回到models/__init__.py,在创建db后导入所有模型。这能确保db在模型类被定义时已经存在,并且方便其他地方一次性导入。
# models/__init__.py 完整版
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
# 在这里导入所有模型
from .user import User
from .product import Product
# 可选:如果你需要,可以导出一个列表
__all__ = ['db', 'User', 'Product']
4. 在Flask应用主文件中初始化 (app.py)
在你的主应用文件中,从models包初始化db。
# app.py
from flask import Flask
from models import db, User, Product # 从我们的models包导入
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///your_database.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 用我们的app初始化db
db.init_app(app)
# 创建数据库表(通常在Flask CLI命令中做,这里仅为示例)
with app.app_context():
db.create_all()
@app.route('/')
def index():
users = User.query.all()
products = Product.query.all()
return f'Users: {users}, Products: {products}'
if __name__ == '__main__':
app.run(debug=True)
关键点总结:
- 一个
db实例:整个项目共享同一个SQLAlchemy实例(在models/__init__.py中创建)。 - 从包导入:在各个model文件中,使用相对导入
from . import db来获取这个共享实例。 - 后导入模型:在
models/__init__.py文件的底部导入所有模型类,这样能避免循环导入问题,也让主应用导入更方便。 - 初始化:在主应用文件(
app.py)中,用db.init_app(app)将数据库实例与你的Flask应用绑定。
这样分文件管理models,结构清晰,也完全遵循了SQLAlchemy的工作方式。直接用这个结构就行。
能详细说下怎么导入吗
贴一下你的导入的语句,还有目录结构
我在附言中添加了
在 db.py 最前面写一句
from houko.models import *
只有一个 model 建表成功应该是因为你在 views 里只调用了一个 model。
btw,这目录结构分的有点诡异=。=
建议把各个 models 扔在 views 同级,改名 models
参照 https://github.com/cburmeister/flask-bones


