2014-10-22 25 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