当分散烧瓶模型时,RuntimeError:'应用程序未注册到数据库'被引发

我正在重新分解我的Flask应用程序,通过分散模型,蓝图,但我有一个运行时错误。

def create_app(): app = flask.Flask("app") app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' app.register_blueprint(api) db.init_app(app) db.create_all() return app 

我有以下问题(示例项目在这里托pipe: https : //github.com/chfw/sample ):

 Traceback (most recent call last): File "application.py", line 17, in <module> app = create_app() File "application.py", line 12, in create_app db.create_all() File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 856, in create_all self._execute_for_all_tables(app, bind, 'create_all') File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 836, in _execute_for_all_tables app = self.get_app(app) File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 809, in get_app raise RuntimeError('application not registered on db 'RuntimeError: application not registered on db instance and no application bound to current context 

我做了一个关于这个话题的研究。 这里build议重新考虑因素:

Flask-SQLAlchemy导入/上下文问题

这里也提出了同样的问题:

http://flask.pocoo.org/mailinglist/archive/2010/8/30/sqlalchemy-init-app-problem/#b1c3beb68573efef4d6e571ebc68fa0b

上面的线程(2010)提出了这样的黑客攻击:

  app.register_blueprint(api) db.app=app #<------------<< db.init_app(app) 

有谁知道如何正确地做到这一点? 你是怎么解决的?

谢谢

这与Flask的应用程序上下文有关 。 当使用db.init_app(app)初始化时,Flask-SQLAlchemy不知道哪个应用程序是“当前”应用程序(请记住,Flask允许在同一个解释器中有多个应用程序 )。 你可以在同一个进程中使用同一个SQLAlchemy实例的多个应用程序,并且Flask-SQLAlchemy需要知道哪个是“当前”的(由于Flask的上下文本地特性)。

如果您需要在运行时执行此操作,则必须明确说出哪个应用程序是所有调用的“当前”应用程序。 您可以通过更改您的代码来执行以下操作:

 def create_app(): app = flask.Flask("app") app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' app.register_blueprint(api) db.init_app(app) with app.app_context(): # Extensions like Flask-SQLAlchemy now know what the "current" app # is while within this block. Therefore, you can now run........ db.create_all() return app 

如果您正在编写需要应用程序上下文的独立脚本,则可以在开始时推送上下文,而不是将所有内容放在一个块中。

 create_app().app_context().push() 

如果您为Flask的cli编写命令,该命令将自动访问上下文。

Mark的回答非常好,对我很有帮助。 然而,另一种解决这个问题的方法是在@ app.before_first_request装饰的函数中运行依赖于应用上下文的代码。 有关更多信息,请参阅http://flask.pocoo.org/docs/0.10/appcontext/ 。 这实际上是我最终做的,主要是因为我想能够在烧瓶外面调用初始化代码,我也是这样处理的。

在我的情况下,我希望能够在没有Flask-SQLAlchemy的情况下将SQLAlchemy模型作为简单的SQLAlchemy模型进行testing,尽pipe下面的代码中的数据库只是一个(Flask)SQLAlchemy数据库。

 @app.before_first_request def recreate_test_databases(engine = None, session = None): if engine == None: engine = db.engine if session == None: session = db.session Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) # Additional setup code