Django迁移SQLite到MySQL报Row size too large错误如何解决
问题根因说明
你添加max_length后报错未消失的核心原因是:Django中TextField的max_length参数仅作用于表单校验环节,不会修改数据库层面的字段类型。MySQL中TEXT/MEDIUMTEXT等大文本类型本身不会全额计入65535的行内限额,仅会在该行存储10字节左右的指针。触发报错的常见原因是模型中存在大量长CharField,或是表的行格式配置不符合要求。
注意:MySQL 65535的行大小限额是数据库服务层的硬限制,无法通过配置直接调高,只能通过以下方案规避。
解决方案
方案1:调整Django模型字段定义
- 排查所有
CharField的max_length设置,长度超过255的字符串字段建议直接改为TextField,CharField的存储长度会全额计入65535的行大小限额,过长的CharField是触发该报错的最常见原因。 - 若业务要求必须保留定长字段,可将部分非高频访问的长字段改为
TextField,减少行内存储占用。
方案2:调整MySQL行格式配置
MySQL InnoDB引擎的DYNAMIC/COMPRESSED行格式支持将超过768字节的变长字段内容存储到页外,仅在该行存储20字节的指针,可大幅降低行内占用,配置方式如下:
- 修改MySQL全局配置,开启
innodb_file_per_table = ON、innodb_default_row_format = DYNAMIC - 对已创建的表执行SQL修改行格式:
ALTER TABLE <你的表名> ROW_FORMAT=DYNAMIC; - 若要在Django迁移中默认生效,可在模型Meta类中添加如下配置:
class YourModel(models.Model): # 此处写你的字段定义 class Meta: db_table = "your_table_name" options = {"row_format": "DYNAMIC"}
方案3:拆分表结构(可选)
如果单表字段确实过多,可将关联度低的大字段拆分到单独的扩展表,通过外键关联,从设计层面避免单页行大小超限。
内容的提问来源于stack exchange,提问作者Prosy A.
相关产品推荐
相关产品推荐

