鍍金池/ 問答/Python  數(shù)據(jù)庫/ 使用Flask-SQLAlchemy項目結(jié)構上如何分離模型?

使用Flask-SQLAlchemy項目結(jié)構上如何分離模型?

看到的例子都是直接在起始程序時直接定義好模型,例如__init__.py, server.py。
我的想法是把模型定義在相應的.py文件中,需要時直接調(diào)用創(chuàng)建,不知道如何組織項目文件以及調(diào)用。
初始化文件:

#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!'

    #初始化數(shù)據(jù)庫
    from app.models import db
    db.init_app(app)
    print('創(chuàng)建數(shù)據(jù)庫。')
    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)

啟動應用正常,但是沒有生成數(shù)據(jù)庫表。

(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
創(chuàng)建數(shù)據(jù)庫。
 * Debugger is active!
 * Debugger PIN: 338-486-377
創(chuàng)建數(shù)據(jù)庫。

為何輸出了兩次“創(chuàng)建數(shù)據(jù)庫”?
訪問應用出現(xiàn)錯誤提示:

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

參考鏈接描述解決如下:
修改初始化文件,使用上下文告知flask模塊當前應用。

    #初始化數(shù)據(jù)庫
    from app.models import db
    db.init_app(app)
    with app.app_context():
        print('創(chuàng)建數(shù)據(jù)庫……')
        db.create_all()
回答
編輯回答
編輯回答
夕顏

每一個初學者都有過這樣的想法,將 models 的對象進行分離,最好能搞成一個 models 的包,然后讓類似于 User 等數(shù)據(jù)庫里的表對象寫成單獨的類文件。這樣的想法很好。但是 Python 本身是不夠友好的,光一個包的互相導入,重復導入的問題就能把人給搞崩潰,建議題主在這個問題上繞道而行。

2017年2月1日 11:20
編輯回答
鹿惑

不太明白你說的“模型”,是指的flask_sqlalchemy.SQLAlchemy類的對象嗎?

2017年5月11日 10:18