2015-12-15 48 views
6

我想用Flask-Migrate,我期待他們的例子:如何在不傳遞數據庫對象的情況下將Flask模型從app.py中分離出來?

from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy 
from flask.ext.script import Manager 
from flask.ext.migrate import Migrate, MigrateCommand 

app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db' 

db = SQLAlchemy(app) 
migrate = Migrate(app, db) 

manager = Manager(app) 
manager.add_command('db', MigrateCommand) 

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(128)) 

if __name__ == '__main__': 
    manager.run() 

這是一個簡單的遊戲例子的偉大工程,但我有比單一模型更多,我不想定義模型在這個腳本和定義我的應用程序代碼的腳本中。因此,我想將它們拖入一個模型文件,我可以在兩者之間共享。

我試圖做到這一點,將User類放入models.py,然後從那裏導入用戶。不幸的是,這拋出了一個NameError: name 'db' is not defined

我的問題(S)是:

  • 我需要在我的models.py使用db = SQLAlchemy(app),如果這樣將本可在我的兩個遷移腳本和燒瓶應用程序本身?
  • 如果我不能(或不應該)把它放在models.py中,我怎麼在不通過db的情況下在自己的文件中使用我的模型?
+0

看看https://realpython.com/blog/python/python-web-applications-with-flask-part-ii/ – PetarP

回答

10

將這樣一個小應用程序分割成模塊是非常棘手的,因爲您發現很多情況下,您創建的兩個模塊需要相互導入,從而創建循環依賴關係。

我建議您看看如何正確構建更大的應用程序,使用應用程序工廠功能並延遲所有擴展的初始化。這樣做的一個示例應用程序是我書中的Flasky應用程序。

說了這麼多,可以將應用程序分成兩部分,你只需要小心放置導入語句的位置。在下面的示例中,我決定將db實例和User模型的創建移動到models.py文件中。

這裏是主要的應用程序的模塊:

from flask import Flask 
from flask.ext.script import Manager 
from flask.ext.migrate import Migrate, MigrateCommand 

app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db' 

from models import db # <-- this needs to be placed after app is created 
migrate = Migrate(app, db) 

manager = Manager(app) 
manager.add_command('db', MigrateCommand) 

if __name__ == '__main__': 
    manager.run() 

這裏是模型。py:

from __main__ import app 
from flask.ext.sqlalchemy import SQLAlchemy 

db = SQLAlchemy(app) 

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(128)) 

這裏主模塊會創建app,然後纔會導入models.py。當models.py嘗試從主模塊導入app時,它已經被創建。如果您將from models import db移動到其他導入文件的頂部,則此代碼會中斷。

+1

我理解你的例子,但是如果我想要將models.py分割成不同的.pys呢?例如User.py,Foo.py,Bar.py.我正在努力尋找一種方法來做到這一點。 –

+1

@VitorHugo你可以創建'models'包,在包的'__init __。py'文件中創建'db'實例,然後爲每個模型添加一個模塊,所有這些模塊都將'db'實例導入爲'from。導入數據庫'。 – Miguel

+0

這工作,但是當我在'from models import db'之後在主應用程序模塊上執行db.create_all()時,它不會創建這些表,這是我在執行models.py時發生的情況。這應該是一個分開的事情,還是應該擔心? –

0

這是一個想法。您可以創建一個包model,其中您將類定義爲單個.py文件。例如,user.py包含User類。

__init__.py文件中,您可以定義db變量。您還可以包含from user import User聲明,以便可以直接在包之外訪問User對象。例如,您可以使用import modelmodel程序包導入程序中的其他位置,然後使用model.User直接使用User類。

直接在user.py使用from ..model import db其中進口在__init__.py文件中定義的變量db使用db變量。

+0

這不是說我需要通過'app'(從' db = SQLAlchemy(app)')而不是'db'? – NewGuy

+0

那麼,在這種情況下,你可以在'__init __。py'中添加'app'和'db' – aliasm2k

相關問題