【问题标题】:Python 2 -> 3 Django migration causes field parameter type changePython 2 -> 3 Django 迁移导致字段参数类型更改
【发布时间】:2019-02-03 01:41:21
【问题描述】:

我们正在从 Django 1.8 -> 2.1 和 Python 2.7 -> 3.6 转换 Django 项目。

在旧项目版本中,有 Django 模型看起来像这样,例如:

# models.py

from django.db import models

class RowStatusModel(models.Model):
    active = models.BooleanField(default=True, db_column='is_active')
    # ...
    class Meta:
        abstract = True

注意from __future__ import unicode_literals 在本模块中没有使用。这意味着 db_column 是 Python 2 的 str,对应于 Python 3 中的 bytes。初始迁移 0001_initial.py 如下所示:

# 0001_initial.py

operations = [
    # ...
    ('row_ef', models.BooleanField(default=True, db_column=b'is_active')
    # ...
]

注意字节文字b'is_active,我想这是由 Django 完成的,目的是为了更明确,但不确定。

现在,在使用 2to3 转换大部分代码库并运行 makemigrations 之后,Python 3 将字符串文字视为 Python 2 中的 unicode 类型,因此会生成 db_column 是字符串文字的迁移,对于从 RowStatusModel 继承的每个模型:

# migrations/0023_auto_20180827_1955.py 
migrations.AlterField(
    # ...
    field=models.BooleanField(default=True, db_column='is_active')
), # ...

./manage.py migrate 运行时,这会对数据库端产生什么影响(如果有的话)? “改变”纯粹是在 Python 方面,还是可能会产生什么副作用?


数据库引擎是django.db.backends.postgresql


我知道,如果migrate 立即导致问题,我们可以克隆 RDS 实例并恢复到该实例,但我更担心引入的更微妙的问题直到很久以后才会被发现。

【问题讨论】:

  • 如该票证的最后一条评论中所述,您只需编辑现有迁移以删除字符串上的 b 前缀。如果您选择生成新生成的迁移,它将不会有任何影响。
  • @BradSolomon 这就是我们在迁移到 Python3 时所做的(更改现有迁移)。没有生成新的迁移,我们也没有任何问题(后端通常是 postgres)。

标签: python django django-migrations


【解决方案1】:

我在问了这个问题后遇到了Django ticket,Django 开发人员的建议是编辑任何包含 (Python 3) 字节文字的旧迁移文件(例如 0001_initial),删除 b 并制作它们是 Python 3 中的字符串文字。

编辑迁移以解决此问题是安全的。

据推测,您应该能够从那里删除使用 python3 ./manage.py makemigrations 进行的迁移模块,然后重做该命令,这应该不再与该参数的类型有问题。

我使用以下方法对'db_column=b' 的所有实例进行了大规模查找和替换,并将'db_column=' 替换为'db_column='。当然,您绝对应该在提交之前检查git diff

grep -nrl "db_column=b" apps | xargs sed -i "s/db_column=b/db_column=/g"

【讨论】:

  • 您可以使用sqlmigrate 命令检查迁移的数据库效果。这种迁移很可能对 db 没有影响。即使字段的choices 参数发生更改,Django 也会生成迁移,而不会产生任何 db 影响。 'no-sql' 迁移还有其他情况。
  • 在更复杂的情况下,编辑所有现有的迁移太耗时,值得考虑简单地生成这个迁移而没有效果,只是为了让 django 开心,然后像往常一样继续(提交,迁移,..)。
猜你喜欢
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
  • 2015-02-07
  • 2013-11-19
  • 2017-10-28
  • 2016-09-10
相关资源
最近更新 更多