Django的Model是按照每次的migrations管理(即app下的migrations包)的。每次更新Model之后,都需要先运行python manage.py makemigrations
进行生成migration,这些migrations中记录了数据库的变更,然后用python manage.py migrate
应用这些更改。
随着项目的增大,migrations也越来越多,每次新的migration都是基于前一次的,也就是说,每次更改数据库,都要把所有的migration走一遍。导致执行migrate的时候速度很慢。比如我们公司的仓库,每次migrate需要二十多分钟。大哥说可以删掉所有的migrations,重新生成,然后用migrate –fake命令“假装执行”,这样做一次,后面的操作都变快了。
今天,我想在自己的项目上用这个方法,于是照着大哥的方法做了遍。本地没有任何问题,做好之后,去服务器操作。结果挂了。服务器的错误如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ python manage.py migrate --fake Traceback (most recent call last): File "manage.py", line 10, in <module> execute_from_command_line(sys.argv) File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line utility.execute() File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/core/management/__init__.py", line 345, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/core/management/base.py", line 348, in run_from_argv self.execute(*args, **cmd_options) File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/core/management/base.py", line 399, in execute output = self.handle(*args, **options) File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 89, in handle executor = MigrationExecutor(connection, self.migration_progress_callback) File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/db/migrations/executor.py", line 20, in __init__ self.loader = MigrationLoader(self.connection) File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/db/migrations/loader.py", line 49, in __init__ self.build_graph() File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/db/migrations/loader.py", line 306, in build_graph _reraise_missing_dependency(migration, parent, e) File "/Users/laixintao/Documents/program/ifenglv/ifenglv_env/lib/python2.7/site-packages/django/db/migrations/loader.py", line 276, in _reraise_missing_dependency raise exc django.db.migrations.exceptions.NodeNotFoundError: Migration user.0001_initial dependencies reference nonexistent parent node (u'auth', u'0008_auto_20160710_1004') |
试过很多办法,甚至把本地的数据库都删掉,也无济于事。
其中的一个尝试让我发现,服务器revert回去,先执行makemigrations,服务器没问题,然后git拉到本地,本地竟然出现了同样的问题。
尼玛,坑爹呢这是。
我打开migrations文件,看了看有个叫做('auth', '0008_auto_20160710_0926')
的依赖,本地找不到。在项目里面全局搜了一下,也没搜到这个文件。
最后用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去生成就行了。