2014-10-22 32 views
5

我正在嘗試拼湊一個小Flask應用程序。這是我的結構。Flask和SQLAlchemy,應用程序未在實例上註冊

run.py 
application 
    __init__.py 
    database.py 
    models.py 
    views.py 

database.py只包含SQLAlchemy的對象:

db = SQLAlchemy() 

我然後導入到我的models.py它來創建我的模型。最後,內部__init__.py我導入dbdatabase.py做:

from .database import db 
from flask import Flask 
app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///application.db' 
db.init_app(app) 
db.create_all() 

但是,我不能創建從它出現在模型中的表。如果我刪除db.create_all()。該應用程序將運行沒有問題,但顯然不創建數據庫。當出現db.create_all()時,我給出'RuntimeError:應用程序未在數據庫實例中註冊,並且沒有綁定到當前上下文的應用程序'。

老實說,我很困惑,因爲之前我在剛創建應用程序時沒有創建數據庫的問題,但將db移動到它自己的文件似乎已經糾正了這個問題。現在,唯一的問題仍然是創建數據庫。

誰能告訴我可能是什麼問題?我真的很難過。

回答

8

答案就在這裏:http://flask-sqlalchemy.pocoo.org/latest/api/#configuration

請參閱有關部分:

The difference between the two is that in the first case methods like create_all() and drop_all() will work all the time but in the second case a flask.Flask.request_context() has to exist.

還有更多的信息在這裏:http://flask-sqlalchemy.pocoo.org/latest/contexts/

如果一切是混淆(它可能是,因爲它在談論Flask的一個相當先進的功能),簡短的短版本是db.init_app(app)更改了app對象,但它不會更改db對象中的任何內容。這是有目的的,因爲可能有不止一個app飛來飛去,而db可能不得不與所有人交談。 (我說這是一個高級功能)。

所以當你沒有請求直接呼叫db.create_all()(它創建一個具有當前運行的全局的app)它不知道連接到什麼和炸彈。這就是錯誤的含義。

在你的情況,我會把SQLAlchemy的回調在__init__.py並通過app給它,這是最簡單的方法:或者讓事情,因爲他們都和第一個請求之前運行安裝

db = SQLAlchemy(app) 

@app.before_first_request 
def create_database(): 
    db.create_all() 

我希望有幫助!如果遇到更多問題,請告訴我。

+0

啊,我明白了。不過,我最終做的是將'app'導入我的模型並在那裏創建'db'對象。這似乎緩解了我所有的問題。 – Battleroid 2014-10-23 02:24:06

+0

很酷,也適用。很高興你能解決它! – 2014-10-23 02:35:07

+4

你也可以這樣做'db.create_all(app = app)'並將'app'參數設置爲你當前的應用程序 – danidee 2016-07-20 15:28:16