使用Flask-SQLAlchemy项目结构上如何分离模型?

wffger
  • 203

看到的例子都是直接在起始程序时直接定义好模型,例如__init__.py, server.py。
我的想法是把模型定义在相应的.py文件中,需要时直接调用创建,不知道如何组织项目文件以及调用。
初始化文件:

#app/__init__.py
import os
from flask import Flask

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)

    # 确保instance目录存在
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    #欢迎页面
    @app.route('/hello')
    def hello():
        return 'Hello, World!'

    #初始化数据库
    from app.models import db
    db.init_app(app)
    print('创建数据库。')
    db.create_all()

    return app

模型文件:

#app/models.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    addresses = db.relationship('Address', backref='person', lazy=True)

class Address(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), nullable=False)
    person_id = db.Column(db.Integer, db.ForeignKey('person.id'),
        nullable=False)

启动应用正常,但是没有生成数据库表。

(Flask-Practice) ydx@ydx-PC:$ flask run
 * Serving Flask app "app" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with inotify reloader
创建数据库。
 * Debugger is active!
 * Debugger PIN: 338-486-377
创建数据库。

为何输出了两次“创建数据库”?
访问应用出现错误提示:

RuntimeError: application not registered on db instance and no application bound to current context

参考链接描述解决如下:
修改初始化文件,使用上下文告知flask模块当前应用。

    #初始化数据库
    from app.models import db
    db.init_app(app)
    with app.app_context():
        print('创建数据库……')
        db.create_all()
回复
阅读 4.2k
4 个回答

不太明白你说的“模型”,是指的flask_sqlalchemy.SQLAlchemy类的对象吗?

每一个初学者都有过这样的想法,将 models 的对象进行分离,最好能搞成一个 models 的包,然后让类似于 User 等数据库里的表对象写成单独的类文件。这样的想法很好。但是 Python 本身是不够友好的,光一个包的互相导入,重复导入的问题就能把人给搞崩溃,建议题主在这个问题上绕道而行。

宣传栏