更改应用程序名称和数据库表后 Django 无法进行迁移

Posted

技术标签:

【中文标题】更改应用程序名称和数据库表后 Django 无法进行迁移【英文标题】:Django can't makemigrations after changing app name and db tables 【发布时间】:2018-06-13 07:47:45 【问题描述】:

我正在使用 Django 1.11.5 并使用 PyCharm 作为我的 IDE。我一直在尝试将我的应用名称从“clinicaltrials”重构为“cancer_trials”。 PyCharm 相应地更新了我的所有项目文件。然后我按照this SO answer 中的步骤更新相应的数据库表。但是,当我尝试运行 makemigration 时出现以下错误。我似乎无法弄清楚这意味着什么和/或我在这里缺少什么部分。

    > python manage.py makemigrations
Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\commands\makemigrations.py", line 150, in handle
    loader.project_state(),
  File "C:\Python_3.6.1\lib\site-packages\django\db\migrations\loader.py", line 323, in project_state
    return self.graph.make_state(nodes=nodes, at_end=at_end, real_apps=list(self.unmigrated_apps))
  File "C:\Python_3.6.1\lib\site-packages\django\db\migrations\graph.py", line 409, in make_state
    project_state = self.nodes[node].mutate_state(project_state, preserve=False)
  File "C:\Python_3.6.1\lib\site-packages\django\db\migrations\migration.py", line 92, in mutate_state
    operation.state_forwards(self.app_label, new_state)
  File "C:\Python_3.6.1\lib\site-packages\django\db\migrations\operations\fields.py", line 142, in state_forwards
    for name, instance in state.models[app_label, self.model_name_lower].fields:
KeyError: ('cancer_trials', 'cancer_trials')

这是引发错误的函数

def state_forwards(self, app_label, state):
    new_fields = []
    old_field = None
    for name, instance in state.models[app_label, self.model_name_lower].fields:
        if name != self.name:
            new_fields.append((name, instance))
        else:
            old_field = instance
    state.models[app_label, self.model_name_lower].fields = new_fields
    # Delay rendering of relationships if it's not a relational field
    delay = not old_field.is_relation
    state.reload_model(app_label, self.model_name_lower, delay=delay)

【问题讨论】:

【参考方案1】:

根据我的经验,最简单的解决方案是创建新应用并复制代码:

    使用所需名称创建新应用并将其添加到设置中 将代码从旧应用复制/粘贴到新应用,将引用从旧应用更改为新应用,运行 makemigrations 并迁移 打开数据库并将旧表中的数据复制到新表中 检查新应用中的一切是否正常

    搜索 ***.com 或谷歌如何从项目中删除应用程序或留在那里。不幸的是,我对这些步骤并不是 100% 肯定,如果我错了,请有人纠正我,但我记得:

    运行python manage.py migrate old_app zero(这将取消应用的所有迁移) 从设置中删除应用 删除文件

【讨论】:

【参考方案2】:

    删除项目中的所有迁移文件 浏览您的每个项目应用程序迁移文件夹并删除其中的所有内容,init.py 文件除外。

    删除当前数据库,或删除 db.sqlite3(如果是您的情况)。

    创建初始迁移并生成数据库架构 尝试再次运行 migrationsa 并迁移命令

【讨论】:

我以前做过这个,但是我不能丢失这个项目中的数据。另外,对于只是想重命名应用程序来说,这似乎有点极端。 不幸的是,这是应用程序名声不好的部分后果。更改名称非常重要。【参考方案3】:

好的 如果您想保留现有数据库,本指南可能会对您有所帮助: https://simpleisbetterthancomplex.com/tutorial/2016/07/26/how-to-reset-migrations.html (场景二)

【讨论】:

【参考方案4】:

关于如何在应用程序之间正确移动数据的一个很好的答案,可以找到here。

对我有用的是:

    将数据导出为json

    ./manage.py dumpdata --exclude auth.permission --exclude contenttypes --exclude admin.LogEntry --exclude sessions --indent 2 > <path_out_of_the_project>/db.json
    

    使用功能强大的编辑器打开db.json 文件,并将old app name 的所有实例重命名为the new app name

    重命名您的应用,并将所有必要的引用重命名到您的代码中。

    删除数据库并重新创建一个新的空数据库以应用所有迁移。

    从包含new app 名称的db.json 文件中加载数据。

    ./manage.py loaddata <path_out_of_the_project>/db.json
    

【讨论】:

【参考方案5】:

简单的方法:

通过进入每个应用的“迁移”命名目录手动删除应用中的所有迁移。 注意:删除 'Migrations' 命名目录中的 init.py 不会造成任何损害。

“appname”上方是逐一采用并使用上述步骤迁移的应用。对于添加的新应用,将仅显示为接下来的两个 'migrate' 和 'sqlmigrate' 命令工作的迁移表。

之后:

$: python manage.py makemigrations appname

$: python manage.py migrate appname

$: python manage.py sqlmigrate appname 0001

【讨论】:

以上是关于更改应用程序名称和数据库表后 Django 无法进行迁移的主要内容,如果未能解决你的问题,请参考以下文章

数据库和Django model 生成和反向生成

sqlserver 2008问题!

在 DB2 中更改表后无法查询

无法更改 Django 管理模板

AWS VPC - 更改路由表后无法从 ec2 实例 ping

在 SQL Server Management Studio 中编辑表后保存更改