Django迁移文件migrations的实现与常见问题解决
本文详细介绍Django中migrations机制的实现原理,涵盖makemigrations与migrate命令的具体用法。针对No changes detected、迁移记录不一致及数据丢失担忧等常见问题,提供回滚、清理django_migrations表及标记已映射等实用解决方案,帮助开发者高效管理数据库结构变更。
Django迁移文件migrations的基本实现
当models.py中的模型定义发生更改,即对数据表结构进行了操作时,数据库表结构随之变化。此时需要使用特定命令来记录这些变更,其作用类似于版本控制的日记。
在修改完models.py文件后,首先需要在终端(Terminal)中执行相关命令。
python manage.py makemigrations
该命令仅用于生成迁移记录,执行后数据库中的表结构并不会立即发生变化。如果models文件已修改但执行上述命令后提示
No changes detected
则需要指定具体的应用目录执行命令:
python manage.py makemigrations + 你所改变的models.py所在的目录
随后,若要使数据库表结构实际发生变化,还需执行以下命令:
python manage.py migrate
执行完毕后,数据库中的表结构即已完成更新。
迁移版本回滚与报错解决方案
补充知识:Django使用migrations迁移版本及数据库中报错解决方案
回滚Django的migration:
https://stackoverflow.com/questions/32123477/django-revert-last-migration
I've made a migration that added a new table and want to revert it and delete the migration, without creating a new migration.
How do I do it? Is there a command to revert last migration and then I can simply delete the migration file?
You can revert by migrating to the previous migration.
For example, if your last two migrations are:
0010_previous_migration
0011_migration_to_revert
Then you would do:
./manage.py migrate my_app 0010_previous_migration
You can then delete migration 0011_migration_to_revert.
If you're using Django 1.8+, you can show the names of all the migrations with
./manage.py showmigrations my_app
To reverse all migrations for an app, you can run:
./manage.py migrate my_app zero
1、进入数据库表django_migrations中查看app列,确认应用信息。

2、在项目对应的app模块中打开migrations文件夹,检查生成的文件与数据库django_migrations表中app列记录是否一致。

3. 找到不一致的文件,然后使用python manage.py --fake [版本名字],将该版本标记为已经映射。
如果仍然报错,请按照以下步骤执行:
1、删除指定app下的migrations文件夹内容,并清理数据库中django_migrations表里与该app相关的版本号记录。
2、确保模型中的字段与数据库中的字段保持一致,再使用命令python manage.py makemigrations重新生成一个初始化的迁移脚本。
3、再使用命令python manage.py makemigrations --fake-initial来将这个初始化的迁移脚本标记为已经映射。此后进行其他修改即可正常进行。
更多关于迁移脚本的详细信息,请查看官方文档:https://docs.djangoproject.com/en/2.0/topics/migrations/
makemigrations与migrate的执行机制
makemigrations和migrate时Django都做了什么?
makemigrations:
执行makemigrations时,Django会检测models文件的变化,并在migrations文件夹中生成包含变更SQL语句的py文件。
migrate:Django会检测django_migrations表,已迁移过的表会记录在其中且不再执行migrate,若未找到执行记录则进行migrate操作。
不要随意删除Django项目目录下的migrations文件夹,里面记录了models文件每次makemigrations操作的历史。误删后,makemigrations会重新生成所有迁移文件。
makemigrations命令常见报错处理
#执行python manage.py makemigrations命令时报错问题及解决办法:
在修改了models.py后,有些用户习惯用python manage.py makemigrations生成对应的py代码。
但有时执行python manage.py makemigrations命令(也可能有人误删了migrations文件夹),会提示“No changes detected.” 可能有用的解决方式如下:
先执行 python manage.py makemigrations --empty yourappname 生成一个空的initial.py文件。
再执行 python manage.py makemigrations 生成原先的model对应的migration file。
migrate命令无效问题排查与解决
Django中关于manage.py migrate无效的问题
问题描述:
已有model,修改之后想重新建模,于是将migrations文件夹中除__init__.py之外的其他文件都删掉,再次执行以下步骤:python manage.py makemigrations确认成功,执行python manage.py migrate,提示No migrations to apply. 此时感到困惑。再次修改指定表名,再次尝试,发现问题依旧,令人费解。
排查过程
执行 python manage.py dbshell 进入数据库,查看是否表已存在。
结果:表不存在。
检查migrations文件。
结果:文件没问题。
通过百度、Google搜索,尝试各种方法。
解决方案
执行 python manage.py dbshell 进入数据库中,执行 delete from django_migrations where app='your_appname'; 删除相关记录。
执行 python manage.py makemigrations(若migrations文件未删除,可不执行这一步)。
执行 python manage.py migrate 即可解决。
原因分析
查看django_migrations表结构。
建表语句:
CREATE TABLE "django_migrations" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "app" varchar(255) NOT NULL, "name" varchar(255) NOT NULL, "applied" datetime NOT NULL);
原因
造成多次应用migrations失败的原因是,当前model是修改过的,原来的migrations已经被删除,但是重新生成的migrations使用递增整数命名,所以在django_migrations表中0001、0002等前面几个数字的文件都已被记录。在Django看来,被记录就等同于已应用,所以会出现刚开始的No migrations to apply提示。
避免方案
有强迫症删除migrations文件的同学(比如我),请同时到数据库中删除相应记录。
没有强迫症的同学,可以继续生成新的migrations,旧的就不必理会了。
题外话
执行python manage.py migrate之后,可以使用python manage.py sqlmigrate appname migrations_num(例如python manage.py sqlmigrate user 0002)查看当前migrations文件对应的SQL语句。
另外,在使用上述命令查看0002文件的SQL语句时发现,Django会新建一个表user_new,然后插入user表中的数据,再把user表删掉,再把user_new重命名为user。所以,修改model的时候,不必担心原有数据会丢失。
临时解决:
在models中添加了一个model,makemigrations成功后,如果migrate提示no apply --》查看django_migrations是否有对应model的name记录,如果没有记录 --》删除model,再次makemigrations、migrate(提示无表,数据库中手动创建对应表名)--》再添加model,再次makemigrations、migrate即可。
上述问题出现的根因:项目目录下面没有留存/migrations/ 文件夹及迁移文件,导致每次项目迁移记得保存好这个目录的文件。
以上这篇Django迁移文件migrations的实现就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









