为什么 Flask Migrations 没有检测到字段的长度变化?

afr*_*afr 5 python postgresql alembic flask-migrate

我有以下模型,我想更改名称的长度,当我进行迁移时,它没有检测到更改

class Client(db.Model):
    __tablename__ = "client"
    client_id = db.Column(
        db.Integer,
        primary_key=True,
        autoincrement=True
    )
    name = db.Column(db.String(65))
    email = db.Column(db.String(255)) 
Run Code Online (Sandbox Code Playgroud)

例如更改为

name = db.Column(db.String(100))

NFO [alembic.env] No changes in schema detected.

但是当我更改名称时,如果它检测到更改

INFO  [alembic.autogenerate.compare] Detected added column 'client.name_test'
INFO  [alembic.autogenerate.compare] Detected removed column 'client.name'
Run Code Online (Sandbox Code Playgroud)

Sup*_*oot 12

更新 - 2020 年 6 月

Alembic 1.4 中的类型比较发生了变化,因此应该更可靠地识别字段长度的变化。从变更日志:

“类型比较”逻辑的主要返工已经到位,它改变了比较列数据类型的整个方法。现在根据元数据类型生成的 DDL 字符串与从数据库反映的数据类型比较类型。这意味着我们根据实际呈现的内容比较类型,此外,如果类型的元素发生变化(如字符串长度),也会检测到这些变化。还应该解决像 SQLAlchemy Boolean 和 MySQL TINYINT 之间生成的误报。非常感谢 Paul Becotte 在这件事上付出的辛勤工作和耐心。

更改日志也引用了这个问题这个文档


原答案

特尔;博士

context.configure(
    # ...
    compare_type = True
)
Run Code Online (Sandbox Code Playgroud)

我已经在 PG 后端的字符串长度更改上对此进行了测试,它确实有效,但是正如您在下面看到的,文档目前声明它不应该。这是文档相关部分

Autogenerate 可以选择检测

  • 更改列类型。如果您将 EnvironmentContext.configure.compare_type 参数设置为 True 或自定义可调用函数,则会发生这种情况。默认实现仅检测主要类型更改,例如 Numeric 和 String 之间的更改,而不检测长度、精度或枚举成员等参数的更改。类型比较逻辑可扩展以解决这些限制,有关详细信息,请参阅比较类型。

以及compare_type状态的 API 参考:

指示自动生成操作期间的类型比较行为。默认为 False 禁用类型比较。设置为 True 以打开默认类型比较,其准确性取决于后端。有关示例以及有关其他类型比较选项的信息,请参阅比较类型。

最后,在标题为“比较类型”的部分中,给出了以下示例以说明如何启用类型比较:

context.configure(
    # ...
    compare_type = True
)
Run Code Online (Sandbox Code Playgroud)

您将context.configure()env.py由嵌套在连接上下文中的 alembic 自动生成的脚本中找到调用:

with connectable.connect() as connection:
    context.configure(
        connection=connection, target_metadata=target_metadata
    )
Run Code Online (Sandbox Code Playgroud)

...然后compare_type在那里添加参数。

在同一部分,他们继续说:

注意默认类型比较逻辑(最终用户可扩展)目前仅适用于类型的主要更改,例如数字和字符串之间的更改。该逻辑不会检测到以下更改:

  • 具有相同“类型关联”的类型之间的变化,例如在 VARCHAR 和 TEXT 之间,或在 FLOAT 和 NUMERIC 之间

  • 类型内参数之间的变化,例如字符串的长度、数字的精度值、枚举内部的元素。

检测这些类型的参数是 SQLAlchemy 方面的一个长期项目。

因此,有趣的是它在文档中多次提到这不应该起作用。如前所述,我已经在 postgres 上对此进行了测试,并且可以确认该设置compare_type=True确实会为该列的长度生成一个修订版,因此文档可能在这方面有点滞后,或者维护人员还没有准备好将其声明为功能呢。

我还在 MySQL 上进行了测试,可以确认如果compare_type=True.