记一次Django数据迁移Bug

Django的Model是按照每次的migrations管理(即app下的migrations包)的。每次更新Model之后,都需要先运行python manage.py makemigrations进行生成migration,这些migrations中记录了数据库的变更,然后用python manage.py migrate应用这些更改。

随着项目的增大,migrations也越来越多,每次新的migration都是基于前一次的,也就是说,每次更改数据库,都要把所有的migration走一遍。导致执行migrate的时候速度很慢。比如我们公司的仓库,每次migrate需要二十多分钟。大哥说可以删掉所有的migrations,重新生成,然后用migrate –fake命令“假装执行”,这样做一次,后面的操作都变快了。

今天,我想在自己的项目上用这个方法,于是照着大哥的方法做了遍。本地没有任何问题,做好之后,去服务器操作。结果挂了。服务器的错误如下:

试过很多办法,甚至把本地的数据库都删掉,也无济于事。

其中的一个尝试让我发现,服务器revert回去,先执行makemigrations,服务器没问题,然后git拉到本地,本地竟然出现了同样的问题。

尼玛,坑爹呢这是。

我打开migrations文件,看了看有个叫做('auth', '0008_auto_20160710_0926')的依赖,本地找不到。在项目里面全局搜了一下,也没搜到这个文件。

migrations-git-diff

最后用pycharm全局搜了一下,找到了…… 从pycharm的颜色可以看出,这并不是在项目中的一个文件,而是site-package的文件,竟然也有migrations,好坑啊……

从git diff可以看出,主要是文件名字的结尾不同。django生成migrations文件的明明规则是 次数+内容+时间的。这个不同得从我管理项目的方式说起。我觉得migrations文件不是项目代码的一部分(不是自动生成的),所以将migrations文件夹放到了gitignore中。每次更新数据库,本地做本地的migrations,服务器做服务器的。这样,就造成时间不同,本地是09:26,服务器是10:04. 两个文件名字不一样……所以有了上文的冲突。

比较好的解决方法是:用git连migrations一起管理着,服务器只执行migrate。说不定什么时候我们还需要手动修改生成的migrations呢!

瞎忙活了一下午,给我的教训是……不要手忙脚乱,认真看报错的信息,慢慢推理吧!慌什么呢!

教训2:还是实践让人学习啊,应该用git管理migrations而不是教给django去生成就行了。

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注