Django 迁移失败

Posted

技术标签:

【中文标题】Django 迁移失败【英文标题】:Django Migrations Failing 【发布时间】:2020-05-29 17:56:09 【问题描述】:

我有两台用于 django 项目的开发机器 - 塔式和笔记本电脑。我使用私人 git 存储库来保持项目同步。我在塔上工作了一段时间,将更改提交到我的 git repo(包括数据库),然后执行 git pull origin master 和 git reset --hard origin/master,然后我在旅行时在笔记本电脑上工作。

我似乎在某个地方犯了一个错误,因为当我如上所述更新笔记本电脑时,我的迁移出现了错误。在塔上,所有迁移都是最新的并已应用。在笔记本电脑上,我有几个无法应用的迁移。

 [X] 0044_remove_document_rotation
 [ ] 0041_remove_collectiondocument_position
 [ ] 0045_merge_20191023_1922
 [X] 0045_auto_20191121_1536
 [ ] 0046_merge_20200213_1523
 [X] 0046_auto_20200213_1541
 [ ] 0047_merge_20200213_1546

这些迁移都在 Tower 上进行了检查。尝试在笔记本电脑上迁移时出现错误:

  Applying memorabilia.0041_remove_collectiondocument_position...Traceback (most recent call last):
  File "./manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/base.py", line 328, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/base.py", line 369, in execute
    output = self.handle(*args, **options)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 233, in handle
    fake_initial=fake_initial,
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/executor.py", line 245, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/migration.py", line 114, in apply
    operation.state_forwards(self.app_label, project_state)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 172, in state_forwards
    delay = not old_field.is_relation
AttributeError: 'NoneType' object has no attribute 'is_relation'

该项目可在塔式电脑和笔记本电脑上运行。

如何在笔记本电脑上应用这些迁移,或删除导致问题的迁移?

【问题讨论】:

【参考方案1】:

当我遇到这样的同步问题时,作为最后的手段,我经常删除迁移并从头开始。为此:

    在迁移文件夹中创建所有迁移的备份(例如,0001.iniital.py 和 0002_auto_20191220_1357.py 以及 myproject/myproject/myapp/migrations/ 中的其他类似文件),然后将其删除。 转到您的 Django 数据库并删除 django.migrations 中的所有条目。 备份您的表,然后将它们从您的 mysql(或其他)数据库中删除。

以上内容将为您提供一个完全干净的状态。

之后:

python manage.py makemigrations

接着是:

python manage.py migrate

如果您的模型设置正确,这将重新创建您的所有结构而不会出错。最后,检查备份的表,并在没有差异的情况下替换现有表。如果存在差异,请确保在同步之前进行必要的数据结构修改。

我发现在处理可管理的数据库大小时,使用这种方法通常比找出迁移的问题链更快。

【讨论】:

Hayden,我过去做过类似的步骤,但我不确定它会如何影响另一台计算机。例如,今天的问题是在笔记本电脑上。因此,如果我按照上述在笔记本电脑上清除迁移并创建新的迁移,然后在笔记本电脑上做一些工作,然后推送到 git repo。当我从 git repo 下拉到 Tower 时,我是否会在迁移时遇到同样的问题,因为它们与以前没有太大的不同?迁移目录在 git 中。 第二个问题。由于我只是将一个工作应用程序推送到 git,使用当前的 mysql 备份,当我从 git 和相应的 mysql 备份中拉下代码库时,我真的需要担心模型和数据库吗?我想我可以只恢复数据库备份并用来自 git 的新东西替换现有的代码库,它应该都可以工作。我错过了什么吗? 由于我经常遇到你描述的问题,我倾向于不将迁移文件提交到 git,而是在我同步到的任何计算机上根据需要运行迁移,从而在每个计算机上创建迁移彼此不同的文件夹。我发现这通常会减少 git 和 Django 让自己陷入的困惑。 回答您的问题:您不必担心,我只是谨慎! @Hayden Eastwood 提交迁移文件被鼓励并在 Django 文档中被提及为最佳实践,请参阅这篇文章 ***.com/a/28035246/12893650。我一直在从事几个 Django 项目。我和其他开发人员提交迁移到 git 的所有项目都顺利进行,唯一导致此处描述的相同问题的项目是我们忽略了迁移并使用 SQL 转储的项目。【参考方案2】:

您是否尝试在笔记本电脑上进行迁移? 这会将迁移标记为已应用,这样您就不会再遇到麻烦了。

伪造单个迁移文件: python manage.py migrate --fake &lt;APP_NAME&gt; &lt;MIGRATION&gt;

伪造应用的所有迁移: python manage.py migrate --fake &lt;APP_NAME&gt;

伪造所有迁移: python manage.py migrate --fake

【讨论】:

首先,我不确定你的问题是什么意思。我目前的情况是,将工作应用程序上传到 git,并从 tower 进行相应的 mysql 备份。我从 git 下载了工作应用程序和从 git 到笔记本电脑的 mysql 备份,它覆盖了笔记本电脑上的旧代码和笔记本电脑上的旧数据库。笔记本电脑和塔现在应该是相同的,除了在笔记本电脑上迁移失败而不是在塔上。其次,在这种情况下,伪造迁移将如何提供帮助? 好的,问题没有解决。您能以某种方式验证您笔记本电脑上的数据库与塔上的数据库相同吗?由于 Django 将有关迁移的信息存储在数据库中,因此应该没有任何区别。无论如何,使用虚假迁移,您可以让 Django 假装它迁移了迁移,而无需实际运行迁移。当我说对时,您的应用程序正在运行,一切似乎都很好。如果是这样,您可以尝试虚假迁移;)

以上是关于Django 迁移失败的主要内容,如果未能解决你的问题,请参考以下文章

在迁移文件中使用特定模型时,Django 测试失败

Django 迁移在 Heroku 中失败

Django 迁移失败 - 无法查询“peterson”:必须是“用户”实例

将 Django 部署到 Elastic Beanstalk,迁移失败

将 m2m 更改为 char 时,Django South 迁移失败

Django 迁移失败并显示“__fake__.DoesNotExist:权限匹配查询不存在”。