Al dispersar modelos de matraz, RuntimeError: ‘la aplicación no registrada en db’ se planteó

Estoy re-factorizando mi aplicación Flask dispersando los modelos, planos, pero estoy teniendo un error de tiempo de ejecución.

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 

Tengo el siguiente problema (el proyecto de muestra está alojado aquí: https://github.com/chfw/sample ):

 Traceback (most recent call last): File "application.py", line 17, in  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 

Hice una investigación sobre este tema. La re-factorización se sugiere aquí:

Flask-SQLAlchemy import / context problem

El mismo problema se planteó aquí:

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

Y el hilo de arriba (2010) sugirió un truco como este:

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

¿Alguien sabía cómo hacer esto correctamente? ¿Cómo lo resolviste?

Gracias

Related of "Al dispersar modelos de matraz, RuntimeError: ‘la aplicación no registrada en db’ se planteó"

Esto tiene que ver con el contexto de aplicación de Flask. Cuando se inicializa con db.init_app(app) , Flask-SQLAlchemy no sabe qué aplicación es la aplicación “actual” (recuerde, Flask permite múltiples aplicaciones en el mismo intérprete). Podría tener varias aplicaciones utilizando la misma instancia de SQLAlchemy en el mismo proceso, y Flask-SQLAlchemy necesitaría saber cuál es la “actual” (debido a la naturaleza local contextual de Flask de todo).

Si necesita hacer esto durante el tiempo de ejecución, debe decir explícitamente qué aplicación es la aplicación “actual” para todas las llamadas. Puedes hacer esto cambiando tu código para usar un with app.app_context() :

 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 

Si está escribiendo un script independiente que necesita el contexto de la aplicación, puede empujar el contexto al principio en lugar de poner todo en un bloque with .

 create_app().app_context().push() 

Si escribe un comando para cli de Flask, el comando tendrá acceso automáticamente al contexto.

La respuesta de Mark fue genial y me ayudó mucho. Sin embargo, otra forma de abordar esto es ejecutar el código que se basa en el contexto de la aplicación en una función decorada con @ app.before_first_request. Consulte http://flask.pocoo.org/docs/0.10/appcontext/ para obtener más información. De hecho, así es como terminé haciéndolo, en gran parte porque también quería poder llamar el código de inicialización fuera del matraz, que manejo de esta manera.

En mi caso, quiero poder probar los modelos SQLAlchemy como modelos SQLAlchemy simples sin Flask-SQLAlchemy, aunque la db en el código a continuación es simplemente una db (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