Django 的数据库迁移有非常多问题,尤其是我们引入了一个维护了非常多年的大插件,比方说 wagtail。
这里总结一些常见问题和解决思路,我自己使用的是 MySQL(MariaDB)
迁移机制
首先说明一下 Django 数据迁移的机制
python manage.py makemigrations
# 在相关应用的 migrations 下会生成迁移文件,记录具体的迁移动作
# 每次迁移动作都会有一个迁移文件,对上一个迁移文件有依赖
python manage.py migrate
# 在数据库中 django_migrations 表中,会有已完成迁移的记录
# 比对 django_migrations 和 现有的迁移文件,对未完成迁移的迁移文件进行处理
# 每完成一个迁移,就记录一条
# --- 出错了 ---
# 已经迁移成功的会记录在 django_migrations 中
# 没有成功的这一条可能执行了一半,对数据库已经产生了影响
# 但是 django_migrations 中不会记录,所以就可能导致反复出错
Specified key was too long
问题:1071, 'Specified key was too long; max key length is 767 bytes'
解决:最常见的问题是数据库使用了 UTF8MB4 编码,可以设置数据库或者 table 的编码为 UTF8
# 设置数据库
alter database name character set utf8;
# 设置表
alter table name character set utf8;
# 设置字段
alter table name modify column varchar(50) CHARACTER SET utf8;
如果是索引太长,可以
set global innodb_large_prefix=on;
set global innodb_file_format=Barracuda;
Duplicate key name 或 Create 失败
通常是某个迁移文件失败了,这个迁移文件执行了一部分,其中包含了增加字段或创建表的操作,因此重复执行就会出错。
需要检查这个迁移文件中相关操作,对数据库中已经进行的操作进行逆操作。
数据库被误删了,怎么恢复
如果是某个应用下的数据库被误删了,最简单的方法是先把 django_migrations
表中的相关迁移记录删除,这个应用相关的数据库可以考虑直接删除,再进行一次 python manage.py migrate
,当然这也意味着这个应用下的所有数据会丢失
不小心删除了迁移文件,数据库都还在怎么办
那就只能“假装”迁移:
那还是 python manage.py makemigrations
生成一下迁移文件,然后 python manage.py migrate --fake
我想从头开始
没问题
- 把 migrations 文件夹下除了
__init__.py
文件外全部删除 - 把
django_migrations
数据库中的相关记录全部删除 - 把所有相关已经创建的数据库删除
python manage.py makemigrations
和python manage.py migrate
重新跑一边
遇到陈年老项目死活搞不定怎么办
参考“我想从头开始”