gpt4 book ai didi

python - 更新模型后 Flask SQLAlchemy 升级失败。需要解释我的修复是如何工作的

转载 作者:太空狗 更新时间:2023-10-30 02:26:17 26 4
gpt4 key购买 nike

我正在阅读一本书来尝试创建一个 Flask 博客。我是 Flask 的新手。我更新了一个模型,因此代码如下所示:

class Entry(db.Model):
STATUS_PUBLIC = 0
STATUS_DRAFT = 1
STATUS_DELETED = 2

id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100))
slug = db.Column(db.String(100), unique=True)
body = db.Column(db.Text)
status = db.Column(db.SmallInteger, default=STATUS_PUBLIC)
created_timestamp = db.Column(db.DateTime, default=datetime.datetime.now)
modified_timestamp = db.Column(
db.DateTime,
default=datetime.datetime.now,
onupdate=datetime.datetime.now)
author_id = db.Column(db.Integer, db.ForeignKey("user.id"))

添加最后一行 author_id = db.Column(db.Integer, db.ForeignKey("user.id")) 导致数据库升级失败并出现错误:

  File "manage.py", line 5, in <module>
manager.run()
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/flask_script/__init__.py", line 412, in run
result = self.handle(sys.argv[0], sys.argv[1:])
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/flask_script/__init__.py", line 383, in handle
res = handle(*args, **config)
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/flask_script/commands.py", line 216, in __call__
return self.run(*args, **kwargs)
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/flask_migrate/__init__.py", line 259, in upgrade
command.upgrade(config, revision, sql=sql, tag=tag)
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/command.py", line 254, in upgrade
script.run_env()
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/script/base.py", line 425, in run_env
util.load_python_file(self.dir, 'env.py')
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/util/pyfiles.py", line 93, in load_python_file
module = load_module_py(module_id, path)
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/util/compat.py", line 75, in load_module_py
mod = imp.load_source(module_id, path, fp)
File "migrations/env.py", line 87, in <module>
run_migrations_online()
File "migrations/env.py", line 80, in run_migrations_online
context.run_migrations()
File "<string>", line 8, in run_migrations
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/runtime/environment.py", line 836, in run_migrations
self.get_context().run_migrations(**kw)
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/runtime/migration.py", line 330, in run_migrations
step.migration_fn(**kw)
File "/home/devblog/projects/blog/app/migrations/versions/6b49bdaf06ce_.py", line 22, in upgrade
batch_op.create_foreign_key(None, 'user', ['author_id'], ['id'])
File "/usr/lib64/python2.7/contextlib.py", line 24, in __exit__
self.gen.next()
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/operations/base.py", line 299, in batch_alter_table
impl.flush()
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/operations/batch.py", line 80, in flush
fn(*arg, **kw)
File "/home/devblog/projects/blog/venv/lib/python2.7/site-packages/alembic/operations/batch.py", line 337, in add_constraint
raise ValueError("Constraint must have a name")
ValueError: Constraint must have a name

问题似乎出在迁移脚本的升级函数上:

def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('entry', schema=None) as batch_op:
#batch_op.create_foreign_key(None, 'user', ['author_id'], ['id'])
batch_op.create_foreign_key("author_id", 'user', ['author_id'], ['id'])

我通过注释掉原始行、删除 None 并使用 'author_id' 来“修复”这个问题。

我在这里使用了文档 http://alembic.zzzcomputing.com/en/latest/ops.html想出解决办法。相关部分:

create_foreign_key(constraint_name, source_table, referent_table, local_cols, remote_cols, onupdate=None, ondelete=None, deferrable=None, initially=None, match=None, source_schema=None, referent_schema=None, **dialect_kw)

This internally generates a Table object containing the necessary columns, then generates a new ForeignKeyConstraint object which it then associates with the Table. Any event listeners associated with this action will be fired off normally. The AddConstraint construct is ultimately used to generate the ALTER statement.

Parameters: name – Name of the foreign key constraint. The name is necessary so that an ALTER statement can be emitted. For setups that use an automated naming scheme such as that described at Configuring Constraint Naming Conventions, name here can be None, as the event listener will apply the name to the constraint object when it is associated with the table. source_table – String name of the source table. referent_table – String name of the destination table. local_cols – a list of string column names in the source table. remote_cols – a list of string column names in the remote table. onupdate – Optional string. If set, emit ON UPDATE when issuing DDL for this constraint. Typical values include CASCADE, DELETE and RESTRICT. ondelete – Optional string. If set, emit ON DELETE when issuing DDL for this constraint. Typical values include CASCADE, DELETE and RESTRICT. deferrable – optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when issuing DDL for this constraint. source_schema – Optional schema name of the source table. referent_schema¶ – Optional schema name of the destination table.

认为我添加了一个约束名称而不是None,它“解决”了这个问题。这是正确的吗?

另外,看起来函数运行需要 5 个参数。仅 4 个如何运作?

非常感谢任何建议。

最佳答案

Mark Steward's solution对于添加一个简单的外键列的情况,对我来说效果很好。

无论您在哪里声明/定义“db”,都请执行以下操作-

from sqlalchemy import MetaData

naming_convention = {
"ix": 'ix_%(column_0_label)s',
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(column_0_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s"
}
db = SQLAlchemy(metadata=MetaData(naming_convention=naming_convention))

然后,在您初始化迁移应用程序 (flask-migrate) 的地方,传递 render_as_batch=True -

migrate.init_app(app, db, render_as_batch=True)

关于python - 更新模型后 Flask SQLAlchemy 升级失败。需要解释我的修复是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45527323/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com