关系“django_content_type”的Django列“名称”不存在

时间:2015-05-30 11:25:04

标签: django django-models

执行迁移时,我一直收到以下错误(python manage.py migrate):

django.db.utils.ProgrammingError: column "name" of relation "django_content_type" does not exist

我已经做了以下尝试修复它但没有成功:

  1. 我删除了每个模型的所有迁移文件
  2. 删除了django_migrations中的所有记录
  3. 运行python manage.py migrate --fake-initial
  4. 运行Django 1.8.2。

    python manage.py showmigrations
    admin
     [ ] 0001_initial
    auth
     [ ] 0001_initial
     [ ] 0002_alter_permission_name_max_length
     [ ] 0003_alter_user_email_max_length
     [ ] 0004_alter_user_username_opts
     [ ] 0005_alter_user_last_login_null
     [ ] 0006_require_contenttypes_0002
    contenttypes
     [X] 0001_initial
     [ ] 0002_remove_content_type_name
    hashtags
     [ ] 0001_initial
     [ ] 0002_hashtagvisit_user
    posts
     [ ] 0001_initial
     [ ] 0002_auto_20150530_0715
    sessions
     [ ] 0001_initial
    users
     [ ] 0001_initial
    

    感谢您的帮助。

11 个答案:

答案 0 :(得分:37)

我今天遇到了同样的问题,我想添加一个问题摘要以及如何解决它:

问题的根源:

Django 1.8更改了其内部数据库结构,数据库中不再存在列name(请参阅is taken from the verbose_name attribute of the model)。

要解决此问题,系统会自动创建迁移contenttypes - 0002_remove_content_type_name

通常,您的所有迁移都应该已经应用,并且应该记录在表django_migrations中,并且一切都应该没问题。

例如,如果您使用dumpdata备份数据库,清除(刷新)所有数据库内容,并使用loaddata加载转储,则django_migrations表仍为空。

因此,migrate尝试再次应用所有迁移(即使您的表存在),并且在尝试删除不存在的列name时失败。

您可以通过检查django_migrations表格来检查这种情况是否适用,或者通过运行python manage.py showmigrations来更加方便。如果您的情况如下

contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name

你很好(或者事实上你遇到了不同的问题),如果它看起来像这样

contenttypes
 [ ] 0001_initial
 [ ] 0002_remove_content_type_name

你遇到了上述情况。请仔细检查,您的数据库是否包含所有表格和所有列(除了您希望对迁移失败应用的更改除外)。

做什么/分步解决方案:

所以我们的数据库结构没问题(除了你想要对失败的迁移应用的更改),但是Django / migrate只是不知道它。那么让我们来做点什么:

  1. 告诉Django,所有内容类型迁移都已应用:manage.py migrate --fake contenttypes。如果要仔细检查,请运行showmigrations

  2. 不要告诉Django,已经应用了要应用的迁移之前的所有迁移。为此,您需要showmigrations所示的迁移号。例如,如果您的情况看起来像

    my_app
     [ ] 0001_initial
     [ ] 0002_auto_20160616_0713
    

    并且migrate在应用0002_auto_20160616_0713时失败,您数据库中最后一次成功应用的迁移为0001_initial。然后Wen通过django_migrations强制执行python manage.py migrate --fake my_app 0001 - 表中的条目(请记住,迁移的数量已足够)。如有必要,migrate会自动伪造所有其他相关迁移。

  3. 现在我们可以应用missiong迁移了,这次我们必须真实而不是伪造!所以我们运行python manage.py migrate my_app。这应该根据需要改变数据库。

    如果您的上次迁移依赖于尚未伪造的其他迁移,则应事先伪造它们。

  4. 仔细检查和清理:再次使用showmigrations检查是否已应用所有迁移。如果有开放式迁移,请使用python manage.py migrate --fake伪造它们。

  5. 你不该做的事

    • 删除所有迁移 - 在生产设置中,这可能不适用,因为它们可能包含一些用于迁移不应丢失的数据的工作。
    • 手动将列name添加到内容类型中 - 之后将在应用迁移时将其删除。好吧,这是一个有效的黑客,但它没有解决问题。

    你应该做的事情

    尝试弄清楚你是如何陷入这种情况并找到避免它的方法。

    我的问题是,我的项目有不同的数据库(用于快速开发测试的sqlite,用于实际测试的本地postgres,用于生产的远程postgres),我想将内容从一个复制到另一个。

答案 1 :(得分:24)

升级到1.8并从MySQL迁移到Postgres时遇到此问题。

我无法解释错误发生的原因,但我能够通过手动添加列来解决这个问题:

  1. 删除所有迁移

  2. django_migrations

  3. 删除记录
  4. 手动添加name列:

    ALTER TABLE django_content_type ADD COLUMN name character varying(50) NOT NULL DEFAULT 'someName';
    
  5. 运行假首字母:$ python manage.py migrate --fake-initial

  6. 编辑12/2016 :我建议将此作为一种解决方法,更适合个人项目或本地环境,而非生产环境。显然,如果你关心你的迁移历史,那就不是这样了。

答案 2 :(得分:4)

在我们决定从版本控制(git)中删除迁移并从头开始创建新数据库之后,我收到了此错误。

对我有用的东西(虽然说实话,我不确定为什么)是为了运行“makemigrations'为每个应用程序。所以,' python manage.py makemigrations app1',' python manage.py makemigrations app2',等等,用于每个Django应用程序。

最后,我刚刚运行' python manage.py migrate',越过我的手指,它运作良好。

任何有关如何/为何如此有效的见解都会有所帮助。

答案 3 :(得分:3)

我知道这是一个老问题,但这可能对某人有所帮助。 我也得到了这个错误。问题是 content_types 有一个名为 0002_remove_content_type_name 的迁移,删除了“name”列。
从表和文件夹中删除迁移数据后,此步骤适用于我:

./manage.py makemigrations myappname
./manage.py migrate myappname
./manage.py migrate --fake contenttypes

如果您确定数据库的其余部分反映了您的迁移,则可以使用:

./manage.py migrate --fake

查看结果:

./manage.py showmigrations

之后,应该标记所有迁移,并且你应该没问题

答案 4 :(得分:1)

我遇到了同样的问题但我能够通过将其添加到我的迁移依赖项中来解决它:

('contenttypes', '0002_remove_content_type_name')

希望它有所帮助!

答案 5 :(得分:1)

对于我来说,我使用以下命令为我的每个 INSTALLED_APPS 运行了 makemigrations

python manage.py makemigrations compressor

使用INSTALLED_APPS更换压缩机。然后使用以下命令成功迁移:

python manage.py migrate

答案 6 :(得分:1)

您的代码的某些部分试图在django_content_type表不存在时尝试访问它,从而导致ProgrammingError。一个工作回合将是将该部分包裹起来,尝试除外。 样本

try:
    seller_content_type = ContentType.objects.get_for_model(Seller)
    add_seller_permission = Permission.objects.get(
        codename='add_seller',
        content_type=seller_content_type,
    )
except ProgrammingError:
    add_seller_permission = None

您实际上可以只用pass替换add_seller_permission = None,但是如果您在其他地方使用该值,则上述内容会有所帮助,因此至少在迁移完成之前,它仍然可用。

答案 7 :(得分:0)

另一个对我有用的变体(来自空白数据库)是:

./manage.py makemigrations myappname
./manage.py migrate

无效的变体是:

./manage.py makemigrations myappname
./manage.py migrate myappname

或者,相反,序列显然会在第一次工作,但第二次不会工作,抱怨django_content_type不存在。

上面的工作(前两行)变体似乎是幂等的。

(编辑:删除原始3行工作版本的冗余第二行)

答案 8 :(得分:0)

我遇到了类似的问题。我最终担任这个职位的方式与其他人一样,我将数据库从一台服务器移动到另一台服务器。发生的事情是我试图通过删除所有迁移文件来修复失败的迁移。这真正做的是删除 0002_remove_content_type_name.py 文件,这就是整个问题对我来说开始的地方。

此文件位于 \venv\Lib\site-packages\django\contrib\contenttypes\migrations 文件夹中。因此,它与您的虚拟环境相关联。我正在复制数据库的服务器拥有自己的虚拟环境(从未复制过),因此文件夹中仍有 0002_remove_content_type_name.py 文件。

对于 Django 来说,这看起来像是一个未应用的迁移。由于我在我的测试服务器中抓取了我的迁移表和所有迁移文件,它总是在我的生产服务器上寻找该迁移。

我如何解决这个问题是将 0002_remove_content_type_name.py 从我的生产服务器复制回我的测试服务器并运行假迁移。所以现在每当我将我的测试数据库复制到 prod 时,这都不会发生。

我也强烈不建议像我一样复制数据库,因为这首先让我遇到了所有这些麻烦。

在我的情况下,如果我没有此文件的副本,则完整的解决方案如下:

  1. 创建一个新的虚拟环境
  2. 从头开始创建一个测试 django 项目
  3. 将新创建的虚拟环境中的 0002_remove_content_type_name.py 复制到我当前项目中的相同位置(\venv\Lib\site-packages\django\contrib\contenttypes\migrations)
  4. 运行“python manage.py showmigrations”以确保它现在已列出
  5. 运行“python manage.py contenttypes --fake

现在所有未来的迁移都应该可以工作,因为它将再次列在迁移表中。

注意:如果您对 Auth 和 Admin 有同样的问题,请对文件执行相同的操作。它们位于虚拟环境中各自的文件夹中。我相信 admin 总共有 3 次迁移,而 auth 有 11 次。我注意到在我修复了我的内容类型问题后这些都消失了。

答案 9 :(得分:0)

我在新数据库上运行 makemigrations(和/或 migrate)时在 Django 3.2 项目中遇到此错误。在这种情况下,问题是我有一行在导入时运行(例如在模块或类级别)访问 ContentTypes,如下所示:

TERM_CONTENT_TYPE = ContentType.objects.get_for_model(Term)

由于在导入期间未创建数据库,因此总是会失败并出现上述错误。

这种情况下的解决方案是将任何类似的数据库交互移动到方法或其他在导入期间不运行的地方。

答案 10 :(得分:-1)

好吧,这些对我来说都不起作用,所以我只是在 postgresql 中删除了我的数据库并创建了一个新数据库,然后运行删除了我以前的迁移文件夹,最后完成了所有迁移,一切正常