随着项目开发进程,对 model 的不断修改将生成越来越多的 migrations 文件,对项目维护造成很多麻烦,所以需要对目前项目里的迁移文件进行合并操作
1. 初始项目
项目此时处于初期,数据库中无重要数据,不担心数据或者表出现问题
- 直接删除各个文件夹下 migration 文件夹中迁移文件
lists=$(ls) for i in $lists;do ls -d $i/migrations/* | grep -v '__init__.py' | xargs rm -rf done
- 重新生成迁移文件并进行迁移
python manage.py makemigrations python manage.py migrate
2. 保留原始表仅合并文件
较为符合实际开发情况,确保无未迁移的 model 修改后,即可开始合并迁移文件
2.1 查询所有 app 的迁移信息
python manage.py showmigrations
如果是分 app 分库的多数据库情况,需要指定 database
参数
python manage.py showmigrations --database=xxx
将得到以下类似输出
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial
share
[X] 0001_initial
[X] 0002_auto_20210923_1451
[X] 0003_auto_20210923_1454
[ ] 0004_bookk
[X]
表示已迁移,[ ]
表示已生成迁移文件但是还没有修改数据库
2.2 将 django 迁移记录标记为未迁移状态
这里仅仅是修改了
django_migrations
表中的迁移记录,并没有对实际数据库表结构造成影响
python manage.py migrate --fake you_app_name zero
如果想到标记某个迁移之前的记录,将 zero 换成迁移文件的序号
skill_test on master [»!?] via 🐍 v3.9.6 (vps-django)
❯ python manage.py migrate --fake you_app_name zero
Operations to perform:
Unapply all migrations: you_app_name
Running migrations:
Rendering model states... DONE
Unapplying imooc.0003_xxxxxxx... FAKED
Unapplying imooc.0002_xxxxxxx... FAKED
Unapplying imooc.0001_initial... FAKED
此时再看迁移状态
skill_test on master [»!?] via 🐍 v3.9.6 (vps-django)
❯ python manage.py showmigrations
you_app_name
[ ] 0001_initial
[ ] 0002_auto_20210923_1451
[ ] 0003_auto_20210923_1454
[ ] 0004_bookk
此时,删除 app
下 migrations
文件夹内的迁移文件,批量删除所有 app 的迁移文件可以使用 第一步中脚本
2.3 重新生成迁移文件并标记已迁移
然后重新生成 migrations
文件
skill_test on master [»!?] via 🐍 v3.9.6 (vps-django) took 2s
❯ python manage.py makemigrations systemime@OpenGo
Migrations for 'you_app_name':
apps/share/migrations/0001_initial.py
- Create model Author
- Create model Country
- Create model Book
- Add field city to author
标记这些更改已迁移
注意 ⚠️ :确保你的更改已经全部落实到数据库,否则该命令会将修改落实到数据库,如果仅仅标记迁移,将
--fake-initial
更改为--fake [you_app_name|空] [版本号]
# 将标记迁移已被执行
python manage.py migrate --fake-initial you_app_name
django_migrations
表将增加迁移的 app 的迁移记录