Django在Galera集群迁移失败,单机MariaDB正常的问题排查
Django迁移Galera集群MariaDB报错:BLOB/TEXT列用于键规范但未指定键长度
问题原因
- 你的
avatar_path字段使用TextField且标记为unique=True,MySQL/MariaDB的InnoDB引擎对TEXT类型字段创建唯一索引时,必须明确指定索引长度,否则会触发1170错误。 - 本地单机环境无报错,核心差异在于Galera集群配置中开启了
innodb_strict_mode=1(参考你提供的my.cnf中InnoDB配置),该严格模式会强制校验索引合法性;而本地单机可能未启用该模式,或使用了对TEXT唯一索引限制更宽松的设置(如旧版本引擎、MyISAM),因此未触发错误。 - 你给
TextField设置的max_length=1000仅在Django表单验证阶段生效,数据库层面不会约束TextField的长度,这也导致数据库无法自动推断索引长度。
解决方案
方案1:替换TextField为CharField(推荐)
既然你已经明确了字段长度上限为1000,完全可以用CharField替代TextField。CharField在数据库层面映射为VARCHAR类型,创建唯一索引时无需额外指定长度,完美匹配需求:
avatar_path = models.CharField(verbose_name="Avatar Path", blank=True, null=True, editable=True, max_length=1000, unique=True)
修改后重新生成迁移文件并执行python manage.py migrate即可。
方案2:保留TextField,手动指定索引长度
若必须保留TextField,需手动指定索引长度。可通过修改迁移文件实现:
- 生成初始迁移文件:
python manage.py makemigrations - 打开对应迁移文件,添加自定义索引并指定长度,示例如下:
from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ # 填写依赖的迁移文件,如('App_Accounts', '0001_initial') ] operations = [ migrations.AlterField( model_name='你的模型名', name='avatar_path', field=models.TextField(blank=True, null=True, verbose_name='Avatar Path'), ), migrations.RunSQL( "CREATE UNIQUE INDEX idx_avatar_path ON 你的表名 (avatar_path(255));", "DROP INDEX idx_avatar_path ON 你的表名;" ) ]
执行迁移即可完成唯一索引的创建。
方案3:关闭innodb_strict_mode(不推荐)
修改Galera集群的my.cnf,将innodb_strict_mode=1改为innodb_strict_mode=0,重启所有MariaDB节点。该方法会关闭InnoDB的严格校验,可能引发数据一致性问题,仅作为临时应急方案。
内容的提问来源于stack exchange,提问作者user20960309
相关产品推荐
相关产品推荐

