解决Django makemigrations 时的NodeNotFoundError

最近做东西的时候换了django,开始用django3.0做。但是在进行makemigrations的时候显示如下错误:

 # 我只截取了最近的报错内容
Traceback (most recent call last):
  File "D:\Python368x64\Lib\site-packages\django\db\migrations\graph.py", line 195, in <listcomp>
    [n.raise_error() for n in self.node_map.values() if isinstance(n, DummyNode)]
  File "D:\Python368x64\Lib\site-packages\django\db\migrations\graph.py", line 58, in raise_error
    raise NodeNotFoundError(self.error_message, self.key, origin=self.origin)
django.db.migrations.exceptions.NodeNotFoundError: Migration auth.0012_user_following dependencies reference nonexistent parent node ('account', '0002_contact')  

通常migrate的错误通过删除上一次的migrate文件即可解决,但是我这明明是个新项目,怎么会出现dependencies的错误呢?
可以看到,最后显示的是dependencies reference nonexistent parent node ('account', '0002_contact'),这显然是某次migrate执行后,在Migrates的class里添加了这个依赖。

那既然不在本项目中自建的app依赖里面,也许是上一次别的项目中app中添加了依赖?
这感觉有点有悖于常理,为什么上一次在别的项目,甚至是别的设备上进行的migrate,会影响到之后新的项目的建表呢?

实际上,如果已经确定不是自建的app的依赖出错,那必然就是django自带的app有问题。
django自带的app那就很多了,好在我能确定是上一次的项目调整了auth的依赖导致migrate文件被添加在了该app下,检查django目录下的migration文件,果然有用户历史的migration文件在里面。


auth app 的migrations

删除确定出错的迁移文件,在这里就是最后一个0012开头的文件,实际上在该文件中也确实定义了相关依赖:


0012_user_following.py

删除它就可以正常执行makemigrations了。


然而潜在的问题还是有的:在使用django的时候,有时也确实会对内置的app进行修改,添加依赖是最简单的一种方式,但是也是最容易耦合的一种方式。这次出错还好只有一个依赖错误,如果是大型项目,迁移文件可能有上百个,而且在多人进行开发的情况下,这种情况很难迅速搞清楚。

虽然django的migrations在数据库中都有表记录,但在这种假设下,你可能需要比对多个数据库的表才能确定究竟是那个项目出了毛病。

所以,尽量使用自建app去继承原有app,不要轻易改原有app的依赖逻辑。一种最简单的做法就是把所有自建app都以尾插的方式放在INSTALLED_APPS里,虽然可能在自建app中有潜在的conflict,但至少不必再排查的时候把历史项目中的几十个app全过一遍了。

我个人觉得django在migration上的设计还是很好的,只是对于不怎么玩django的人来说很多错误排查起来难以下手。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容