Django将字段改为TextField的迁移在MySQL 9.0.1中失败问题咨询
解决MySQL下Django TextField加索引报错1170的问题
问题根源
MySQL规定,给TEXT、BLOB类型字段创建索引时必须指定索引长度,但Django里TextField(db_index=True)的默认配置不会自动添加这个长度限制,所以在MySQL 9.0.1+Django 5.1.5环境下触发了1170错误。
可行修复方案
1. 换成带长度限制的CharField(优先推荐)
如果收件人地址的实际长度不会太长,直接把TextField改成CharField:
migrations.AlterField( model_name='mailermessage', name='to_address', field=models.CharField(max_length=255, db_index=True, verbose_name='To'), ),
先确认现有数据里的
to_address字段值都不超过255字符,否则迁移会失败。
2. 给TextField的索引指定长度(Django 2.2+可用)
Django 2.2及以后版本支持给TextField的索引传长度参数,修改迁移代码如下:
migrations.AlterField( model_name='mailermessage', name='to_address', field=models.TextField( db_index={'length': 255}, verbose_name='To' ), ),
这样生成的SQL会自动带上INDEX (to_address(255)),满足MySQL的要求。
3. 手动写原生SQL迁移
如果前两种方法不合适,直接用原生SQL创建索引:
替换原来的AlterField操作,改成RunSQL:
migrations.RunSQL( # 正向SQL:创建带长度的索引 "CREATE INDEX mailermessage_to_address_idx ON mailermessage(to_address(255));", # 回滚SQL:删除索引 "DROP INDEX mailermessage_to_address_idx ON mailermessage;", ),
注意调整表名和索引长度,回滚语句要和正向对应。
验证与生产环境说明
- 运行
python manage.py sqlmigrate <你的app名> <迁移编号>,看生成的SQL里有没有带长度的索引语句(比如to_address(255)),有的话就说明修复有效。 - 这个问题肯定会在生产环境复现,只要是MySQL环境,对TEXT字段建索引都有长度要求,必须修复后再部署。
内容的提问来源于stack exchange,提问作者Mike Robinson
相关产品推荐
相关产品推荐

