Django旧迁移文件引用django_mysql.models.JSONField报错如何处理
Django升级后历史迁移文件JSONField属性报错处理方案
问题背景
旧版本Django无内置JSON字段支持,需通过django_mysql.models.JSONField在模型中定义JSON类型字段。高版本Django配套的django-mysql库已将JSONField从django_mysql.models模块移除,当前已完成所有models.py文件的适配修改,但项目中留存的历史生成迁移文件仍引用旧路径,导致迁移命令执行失败。
环境信息
- Django 4.0
- Python 3.9.13
- django-mysql 4.7.0
异常复现
问题迁移文件内容:
# Generated by Django 2.1.7 on 2019-07-17 22:59 from django.db import migrations import django_mysql.models class Migration(migrations.Migration): dependencies = [ ('rss', '0009_delete_patternmatchingkeywords'), ] operations = [ migrations.AddField( model_name='rssoutput', name='industries', field=django_mysql.models.JSONField(default=list), ## 报错位置 ), ]
执行makeMigration命令抛出错误:
AttributeError: module 'django_mysql.models' has no attribute 'JSONField'
标准处理流程
- 禁止直接删除历史迁移文件:历史迁移是数据库结构演进的可信记录,删除会破坏迁移依赖链,在多环境部署、存量数据库、CI/CD流水线场景下会引发数据库结构不一致、迁移冲突等更严重的问题。
- 逐份修复存在旧引用的迁移文件:Django 3.1及以上版本已内置兼容MySQL的
JSONField,行为、存储结构与原django-mysql提供的JSONField完全一致,仅需替换引用来源即可,不需要修改迁移的操作逻辑、依赖关系:- 将文件头部的
import django_mysql.models替换为from django.db import models(如果已有django.db的models导入可跳过这步) - 将字段定义处的
django_mysql.models.JSONField替换为models.JSONField,保留原有参数(比如示例中的default=list)
修复完成后的迁移文件参考:
# Generated by Django 2.1.7 on 2019-07-17 22:59 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('rss', '0009_delete_patternmatchingkeywords'), ] operations = [ migrations.AddField( model_name='rssoutput', name='industries', field=models.JSONField(default=list), ), ] - 将文件头部的
- 全局扫描排查所有历史迁移文件:全局搜索项目中所有迁移文件内的
django_mysql.models.JSONField引用,按照上述规则全部替换完成,避免后续运行其他历史迁移时触发同类错误。 - 修复结果校验:
- 执行
python manage.py makemigrations --check,确认命令无报错,且不会生成新的冗余迁移文件 - 使用空的测试数据库执行全量
migrate命令,确认所有迁移可以从头正常执行完成 - 对于已经执行过旧版本迁移的存量数据库,不需要额外执行数据转换操作,两种JSONField的数据库层存储逻辑完全一致,不会出现数据读写兼容问题。
- 执行
内容的提问来源于stack exchange,提问作者VikR
相关产品推荐
相关产品推荐

