Flask和SQLAlchemy,应用程序未在实例上注册

Bat*_*oid 5 python sqlalchemy flask flask-sqlalchemy

我正在尝试拼凑一个小型Flask应用程序.这是我的结构.

run.py
application
  __init__.py
  database.py
  models.py
  views.py
Run Code Online (Sandbox Code Playgroud)

database.py 仅包含SQLAlchemy对象:

db = SQLAlchemy()
Run Code Online (Sandbox Code Playgroud)

然后我将其导入到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()
Run Code Online (Sandbox Code Playgroud)

但是,我无法从它出现的模型中创建表.如果我删除db.create_all().应用程序将运行没有问题,但显然没有创建数据库.当db.create_all()存在时,我被赋予'RuntimeError:应用程序未在db实例上注册,并且没有应用程序绑定到当前上下文'.

老实说我很困惑,因为我之前只是在没有创建数据库的情况下启动应用程序时出现问题,但转移db到它自己的文件似乎已经在某种程度上纠正了这个问题.现在,唯一的问题仍然是创建数据库.

谁能告诉我可能是什么问题?我真的很难过.

Rac*_*ers 8

答案在这里:http: //flask-sqlalchemy.pocoo.org/latest/api/#configuration

请参阅以下部分:

两者之间的区别在于,在第一种情况下,create_all()和drop_all()等方法将一直有效,但在第二种情况下,必须存在flask.Flask.request_context().

这里有更多信息: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)
Run Code Online (Sandbox Code Playgroud)

或保持原样,并在第一次请求之前运行设置:

@app.before_first_request
def create_database():
     db.create_all()
Run Code Online (Sandbox Code Playgroud)

我希望有所帮助!如果您遇到更多问题,请告诉我.

  • 你也可以这样做`db.create_all(app = app)`并将`app`参数设置为你当前的应用程序 (5认同)