Django从SQLite迁移至MySQL时表未创建报错排查
核心根因
两个独立问题叠加导致所有操作卡壳:
- 应用启动逻辑存在硬伤:
ekichabi_demo.py在模块加载/应用初始化阶段就直接查询业务表,Django执行任何manage.py命令(包括migrate、loaddata)时都会先加载全量应用代码,此时MySQL里还没创建业务表,查询直接触发1146表不存在错误,导致所有命令都无法执行。 - 数据库兼容问题:SQLite允许AutoField(自增主键)存储0值,但MySQL InnoDB引擎默认不接受自增列写入0值,直接迁移数据会触发AutoField 0值校验报错。
解决步骤
- 临时屏蔽启动阶段的数据库查询逻辑
定位ekichabi_demo.py中初始化HomeScreen实例、查询ekichabidemo_business表的代码,不要在模块顶层直接执行这类查询,增加命令和表存在判断,示例如下:
修改完成后,任意import sys from django.db import connection def init_home_screen(): # 先校验业务表是否存在,不存在直接跳过初始化 with connection.cursor() as cursor: cursor.execute("SHOW TABLES LIKE 'ekichabidemo_business'") if not cursor.fetchone(): return # 原有初始化逻辑放在这 HomeScreen() # 仅在启动web服务时执行初始化,migrate、loaddata等管理命令阶段跳过 if len(sys.argv) > 1 and sys.argv[1] == 'runserver': init_home_screen()manage.py命令不会再启动即报表不存在错误。 - 导出干净的源数据
先将settings中的数据库配置切回原SQLite,确认原应用运行正常,执行以下命令导出数据,排除Django自动生成的contenttypes、auth权限表数据——这两类表会在migrate阶段自动生成,强行导入很容易引发主键冲突、自增字段值异常:python manage.py dumpdata --exclude contenttypes --exclude auth.Permission --indent 2 > dump_clean.json - 清理MySQL残留环境
切回MySQL数据库配置,删除所有app下migrations目录内除__init__.py之外的所有文件,登录MySQL执行以下语句重建空库,清除之前建表失败的残留数据:
编辑MySQL配置文件,在DROP DATABASE IF EXISTS test629; CREATE DATABASE test629 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;[mysqld]配置段添加sql_mode = NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO,保存后重启MySQL服务,该配置允许MySQL自增列接受0值,解决AutoField 0值报错问题。 - 执行表结构迁移和数据导入
按顺序执行以下命令,不要打乱顺序:python manage.py makemigrations生成全量业务表迁移文件python manage.py migrate执行迁移,在MySQL中创建完整的表结构python manage.py loaddata dump_clean.json导入之前导出的干净业务数据
- 验证功能
执行python manage.py runserver启动服务,验证所有业务功能正常、数据完整即可。后续调整初始化逻辑时,不要在应用顶层加载阶段直接执行数据库查询,避免再次出现管理命令执行失败的问题。
内容的提问来源于stack exchange,提问作者ekichabiv2
相关产品推荐
相关产品推荐

