Django迁移MySQL遇1170错误:TEXT字段用于唯一约束未指定长度
解决Django改TextField后MySQL迁移报错1170的问题
问题根源
MySQL不允许直接把TEXT/BLOB类型字段放在唯一约束里,因为这类字段做索引必须指定长度,而Django 2.2的unique_together机制不会自动给TextField添加索引长度,所以迁移时触发1170错误。
可行解决方案(针对Django 2.2.2)
方案1:用indexes替代unique_together,手动指定索引长度
直接修改模型的Meta类,移除原有的unique_together,改用indexes创建带长度限制的唯一索引:
from django.db import models class YourModel(models.Model): my_column = models.TextField() # 已修改为TextField的字段 other_field = models.CharField(max_length=100) # 原unique_together中的其他字段 class Meta: # 替换原有unique_together配置 indexes = [ # 给my_column指定索引长度,可根据业务需求调整(比如255、512) models.Index(fields=['my_column(255)', 'other_field'], name='unique_mycol_other_idx', unique=True) ]
执行python manage.py makemigrations生成新迁移文件,再运行python manage.py migrate完成迁移。
方案2:手动修改迁移文件
如果不想改动模型代码,可按以下步骤操作:
- 先执行
python manage.py makemigrations生成初始迁移文件 - 打开生成的迁移文件,找到处理唯一约束的代码块,将字段名改为带长度的格式:
比如原迁移代码可能是:
operations = [ migrations.AlterUniqueTogether( name='yourmodel', unique_together={('my_column', 'other_field')}, ), ]
修改为:
operations = [ # 先移除原有唯一约束(若之前已存在) migrations.AlterUniqueTogether( name='yourmodel', unique_together=set(), ), # 添加带长度限制的唯一索引 migrations.AddIndex( model_name='yourmodel', index=models.Index(fields=['my_column(255)', 'other_field'], name='unique_mycol_other_idx', unique=True), ), ]
- 运行
python manage.py migrate完成迁移
注意事项
- 索引长度需根据业务需求调整,InnoDB引擎下索引长度一般不超过767字节,可根据字符编码换算(比如utf8mb4下255个字符刚好是1020字节,超过限制的话可改短)
- 执行迁移前建议备份数据库,避免数据风险
内容的提问来源于stack exchange,提问作者DilLip_Chowdary
相关产品推荐
相关产品推荐

