You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django在Galera集群迁移失败,单机MariaDB正常的问题排查

Django迁移Galera集群MariaDB报错:BLOB/TEXT列用于键规范但未指定键长度

问题原因

  1. 你的avatar_path字段使用TextField且标记为unique=True,MySQL/MariaDB的InnoDB引擎对TEXT类型字段创建唯一索引时,必须明确指定索引长度,否则会触发1170错误。
  2. 本地单机环境无报错,核心差异在于Galera集群配置中开启了innodb_strict_mode=1(参考你提供的my.cnf中InnoDB配置),该严格模式会强制校验索引合法性;而本地单机可能未启用该模式,或使用了对TEXT唯一索引限制更宽松的设置(如旧版本引擎、MyISAM),因此未触发错误。
  3. 你给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,需手动指定索引长度。可通过修改迁移文件实现:

  1. 生成初始迁移文件:python manage.py makemigrations
  2. 打开对应迁移文件,添加自定义索引并指定长度,示例如下:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:05:22