python - 向现有 django 模型添加新的唯一字段时的最佳实践

标签 python django python-3.x database-migration django-migrations

我有一个现有的模型,看起来有点像下面这样......

class Resource(models.Model):

    id = models.AutoField(primary_key=True)

我们已经使用它一段时间了,现在我们的数据库中有这些 Resource 对象(以及相关的 ForeignKey/else 用法)的大约 1M 个实例。

我现在需要跟踪此模型上的另一个 ID,我想强制执行的 ID 是唯一的。
other_id = models.IntegerField(unique=True)

other_id 信息当前存储在一些外部 CSV 中,我想(在此过程中的某个时刻)将此信息加载到所有现有的 Resource 实例中。

添加上述字段后,Django 的 makemigrations 工作正常。但是,当我对现有数据库应用所述迁移时,我收到一条错误消息,表明我需要提供一个默认值以用于所有现有 Resource 实例。相信很多人都见过类似的情况。

解决此限制的最佳方法是什么?我想到的一些方法...
  • 删除 unique=True 要求
  • 应用迁移
  • other_id 值从外部加载到所有现有模型(通过某些管理命令或 1-off 脚本)
  • 重新添加 unique=True 并应用迁移
  • 将所有现有数据转储到 JSON
  • 刷新所有表
  • 应用迁移(unique=True)
  • 编写一个重新加载数据的脚本,添加正确的 other_id
  • (不确定这是否可行)- 编写一些自定义迁移逻辑以在运行 other_id 时自动引用这些外部 CSV 以加载 manage.py migrate 值。如果(在将来的某个时候)有人重新运行这些迁移并且这部分失败(无法在 CSV 中找到现有资源 id 以提取 other_id ),这可能会遇到问题。

  • 所有这些都感觉很复杂,但话说回来,我想我想做的也不是最简单的事情。

    有任何想法吗?我不得不想象过去有人不得不解决类似的问题。

    谢谢!

    最佳答案

    实际上,来源或您的问题本身并不是唯一约束,而是您的字段不允许空值且没有默认值这一事实 - 对于非唯一字段,您会遇到相同的错误。

    这里正确的解决方案是允许该字段为空( null=True )并将其默认为 None (这将转换为 sql "null")。由于 null 值被排除在唯一约束之外(至少如果您的数据库供应商遵守 SQL 标准),这允许您应用架构更改,同时仍然确保您不能有非空值的重复项。

    然后,您可能需要数据迁移以加载已知的“other_id”值,并最终进行第三次架构迁移以禁止此字段的空值 - 当且仅当您知道已为所有记录填充此字段时。

    关于python - 向现有 django 模型添加新的唯一字段时的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56934804/

    相关文章:

    python-3.x - 如何使用Socket库使用python3连接到ipv6主机

    python - 在 numpy 中用零替换除零错误

    超过 Python Telegram Bot 洪水控制

    python - Django ORM,如何使用 values() 并仍然使用 choicefield?

    使用 Ajax 的 Javascript POST 到 Django 不起作用

    python - 如何存储 bash 命令的输出?

    python - 来自循环的堆积条形图不添加不同的条形组件

    python - 获取数据框中出现项目值的所有时间

    python - 过期后自动从订阅数据库中删除项目?

    python - Tshark 不通过 subprocess.Popen 执行