python - flask db init 返回“sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table”
问题描述
我一直在使用 sqlite 数据库在烧瓶中开发一个 Web 应用程序。到目前为止一切顺利,我知道一旦数据库存在,sqlite 在对表的更改方面受到限制。
但是,到目前为止,我已经能够毫无问题地修改 models.py 中几个模型的表(添加列、重命名列等)。注意到这里我确实使用
migrate = Migrate(app, db, render_as_batch=True)
在应用程序初始化中,已经需要实现对数据库的一些更改。
flask db migrate
但是,现在,在向模型“用户”添加新列后尝试运行时,我收到了以下错误:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1249, in _execute_context
cursor, statement, parameters, context
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/default.py", line 580, in do_execute
cursor.execute(statement, parameters)
sqlite3.OperationalError: no such table: user
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/bin/flask", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.6/dist-packages/flask/cli.py", line 966, in main
cli.main(prog_name="python -m flask" if as_module else None)
File "/usr/local/lib/python3.6/dist-packages/flask/cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/click/decorators.py", line 21, in new_func
return f(get_current_context(), *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/flask/cli.py", line 425, in decorator
with __ctx.ensure_object(ScriptInfo).load_app().app_context():
File "/usr/local/lib/python3.6/dist-packages/flask/cli.py", line 388, in load_app
app = locate_app(self, import_name, name)
File "/usr/local/lib/python3.6/dist-packages/flask/cli.py", line 240, in locate_app
__import__(module_name)
File "/home/arthur/Development/ISLWeb/islweb.py", line 1, in <module>
from app import app, db
File "/home/arthur/Development/ISLWeb/app/__init__.py", line 24, in <module>
from app import routes, models
File "/home/arthur/Development/ISLWeb/app/routes.py", line 11, in <module>
from app.forms import (LoginForm, RegistrationForm, CreateLaunchForm,
File "/home/arthur/Development/ISLWeb/app/forms.py", line 93, in <module>
class NewActionForm(FlaskForm):
File "/home/arthur/Development/ISLWeb/app/forms.py", line 95, in NewActionForm
users = User.query.all()
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/query.py", line 3186, in all
return list(self)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/query.py", line 3342, in __iter__
return self._execute_and_instances(context)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/query.py", line 3367, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 988, in execute
return meth(self, multiparams, params)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/sql/elements.py", line 287, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1107, in _execute_clauseelement
distilled_params,
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1253, in _execute_context
e, statement, parameters, cursor, context
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1473, in _handle_dbapi_exception
util.raise_from_cause(sqlalchemy_exception, exc_info)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/util/compat.py", line 398, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/util/compat.py", line 152, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py", line 1249, in _execute_context
cursor, statement, parameters, context
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/default.py", line 580, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user
[SQL: SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email, user.password_hash AS user_password_hash, user.has_admin_rights AS user_has_admin_rights, user.is_customer AS user_is_customer
FROM user]
(Background on this error at: http://sqlalche.me/e/e3q8)
这对我来说很奇怪,因为:
- 表用户在(并且已经)在那里
- 我之前已经能够向用户模型添加列
- 我仍然可以将列添加到其他模型而不会出现错误
现在,我在这里和其他地方的许多问题中都看到了这个 sqlite3.OperationalError ,但它们似乎都与这里的情况无关,因为代码库之前运行良好,迁移也是如此(它们仍然与所有其他模型也是如此)另外,我尝试作为一种测试方式删除迁移文件夹以及数据库文件,重新开始:
flask db init
在我的理解中,它重新启动了整个数据库(包括新的迁移脚本)。有趣的是,这会引发与上述完全相同的错误。我也完全不明白,因为没有数据库可供读取。
我的用户模型如下(我试图添加评论的列):
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
actions = db.relationship('Action', backref='owner', lazy='dynamic')
events = db.relationship('WebLogEvent', backref='user', lazy='dynamic')
has_admin_rights = db.Column(db.Boolean)
is_customer = db.Column(db.Boolean)
#permissions = db.Column(db.String(256), index=True)
def __repr__(self):
return '<User {}>'.format(self.username)
@staticmethod
def table_header():
return ["ID", "Username", "e-mail", "Admin"]
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
def as_table_row(self):
return [self.id, self.username, self.email, self.has_admin_rights]
任何关于这里可能出现的问题的想法都非常受欢迎。
解决方案
您正在应用程序的全局范围内发出查询,在 class 中NewActionForm
。User.query.all()
根据您的堆栈跟踪,查询是。
问题在于全局范围内的代码在导入时执行。在很多情况下这没问题,但是数据库访问通常是有问题的,因为您必须在访问数据库之前创建和配置您的 Flask 应用程序实例。
所以解决办法是不在全局范围内查询数据库。您可能可以将该逻辑移动到表单的构造方法中。
推荐阅读
- c# - 数据列表不显示项目 ASP.NET
- php - 如何使用 Laravel 表单验证检查提交到数据库的数据是否唯一?
- javascript - 为什么页面重新加载后框架选择会中断?
- python - 由于“错误:需要 Microsoft Visual C++ 14.0”,无法使用 pip 安装 Earl-etf,但我已经拥有所有 MS C++ 构建工具
- c++ - 为什么以下 3 个版本中的 2 个 std::visit 不起作用
- javascript - 我应该有 2 个不同的端点来根据查询参数获取所有品牌和获取品牌吗?
- css - 我可以控制使用多列 CSS 的 HTML 列表中的分栏符吗?
- javascript - 角度验证中的输入“触摸”正在阻止方法执行
- database - 在构建 LoadDataFromFireStore 时引发了以下 NoSuchMethodError。在 null 上调用了 getter 'keys'
- c# - 如何使用 LINQ 过滤不为 null 的属性并获取其值来运行方法?