Bra*_*mon 11 python django django-migrations
我们正在从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
Run Code Online (Sandbox Code Playgroud)
请注意,from __future__ import unicode_literals
是不是这个模块中使用.这意味着它db_column
是Python 2 str
,与bytes
Python 3 相对应.初始迁移0001_initial.py如下所示:
# 0001_initial.py
operations = [
# ...
('row_ef', models.BooleanField(default=True, db_column=b'is_active')
# ...
]
Run Code Online (Sandbox Code Playgroud)
请注意字节文字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')
), # ...
Run Code Online (Sandbox Code Playgroud)
./manage.py migrate
运行时,这会对数据库端产生什么影响?"改变"纯粹是在Python方面,还是可以创建什么副作用?
数据库引擎是django.db.backends.postgresql
.
我知道我们可以克隆RDS实例并恢复到那个如果migrate
导致直接问题,但我更关注引入的更微妙的问题,直到很久以后才会被捕获.
问完这个问题后,我碰到了一张Django票证,Django开发人员的建议是编辑包含(Python 3)字节文字的任何旧版迁移文件(例如0001_initial),然后删除,b
并在Python 3 中将其制成字符串文字。 。
编辑迁移以解决此问题是安全的。
您大概应该可以从那里删除使用制作的迁移模块,python3 ./manage.py makemigrations
并重做该命令,该命令不再与该参数的类型有关。
我使用以下代码对'db_column=b'
with 的所有实例进行批量查找和替换'db_column='
。当然,git diff
在进行该提交之前,您应该绝对检查一下。
grep -nrl "db_column=b" apps | xargs sed -i "s/db_column=b/db_column=/g"
Run Code Online (Sandbox Code Playgroud)