【问题标题】:Why Flask Migrations does not detect a field's length change?为什么 Flask Migrations 没有检测到字段的长度变化?
【发布时间】:2019-10-24 00:20:01
【问题描述】:

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

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)) 

例如更改为

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'

【问题讨论】:

    标签: python postgresql alembic flask-migrate


    【解决方案1】:

    更新 - 2020 年 6 月

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

    对“类型比较”逻辑进行了重大修改 更改比较列数据类型的整个方法。 类型现在根据生成的 DDL 字符串进行比较 元数据类型与从数据库反映的数据类型。这表示 我们根据实际渲染的内容比较类型,此外 如果类型的元素像字符串长度一样发生变化,则这些变化是 也被检测到。像之间产生的误报 SQLAlchemy Boolean 和 MySQL TINYINT 也应该被解析。谢谢 非常感谢保罗·贝科特为此付出了很多努力和耐心 一个。

    更改日志还引用了this issuethis documentation


    原答案

    TL;DR

    context.configure(
        # ...
        compare_type = True
    )
    

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

    Autogenerate 可以选择性地检测

    • 更改列类型。如果您设置 EnvironmentContext.configure.compare_type 参数为 True,或为 自定义可调用函数。默认实现只检测 主要类型更改,例如在 Numeric 和 String 之间,而 不会 检测参数的变化,例如长度、精度或 枚举成员。类型比较逻辑可扩展工作 有关这些限制,请参阅比较类型了解详情。

    compare_type 的 API 参考声明:

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

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

    context.configure(
        # ...
        compare_type = True
    )
    

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

    with connectable.connect() as connection:
        context.configure(
            connection=connection, target_metadata=target_metadata
        )
    

    ... 只需在其中添加 compare_type 参数。

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

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

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

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

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

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

    我还在 MySQL 上进行了测试,并且可以确认如果 compare_type=True 时字符串长度更改也会被拾取。

    【讨论】:

    • 这里有超级答案!谢谢。
    猜你喜欢
    • 2021-11-01
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 2020-04-18
    相关资源
    最近更新 更多