鍍金池/ 問(wèn)答/Python  數(shù)據(jù)庫(kù)/ 使用Flask-SQLAlchemy項(xiàng)目結(jié)構(gòu)上如何分離模型?

使用Flask-SQLAlchemy項(xiàng)目結(jié)構(gòu)上如何分離模型?

看到的例子都是直接在起始程序時(shí)直接定義好模型,例如__init__.py, server.py。
我的想法是把模型定義在相應(yīng)的.py文件中,需要時(shí)直接調(diào)用創(chuàng)建,不知道如何組織項(xià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

    #歡迎頁(yè)面
    @app.route('/hello')
    def hello():
        return 'Hello, World!'

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

啟動(dòng)應(yīng)用正常,但是沒(méi)有生成數(shù)據(jù)庫(kù)表。

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

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

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

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

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

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

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

不太明白你說(shuō)的“模型”,是指的flask_sqlalchemy.SQLAlchemy類的對(duì)象嗎?

2017年5月11日 10:18