Python django.db.utils.ProgrammingError: 关系已经存在

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29830928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 05:03:45  来源:igfitidea点击:

django.db.utils.ProgrammingError: relation already exists

pythondjangopostgresqlubuntu

提问by quindraco

I'm trying to set up the tables for a new django project (that is, the tables do NOT already exist in the database); the django version is 1.7 and the db back end is PostgreSQL. The name of the project is crud. Results of migration attempt follow:

我正在尝试为新的 django 项目设置表(即,数据库中尚不存在这些表);django 版本是 1.7,数据库后端是 PostgreSQL。该项目的名称是 crud。迁移尝试的结果如下:

python manage.py makemigrations crud

python manage.py makemigrations crud

Migrations for 'crud':
  0001_initial.py:
    - Create model AddressPoint
    - Create model CrudPermission
    - Create model CrudUser
    - Create model LDAPGroup
    - Create model LogEntry
    - Add field ldap_groups to cruduser
    - Alter unique_together for crudpermission (1 constraint(s))

python manage.py migrate crud

python manage.py migrate crud

Operations to perform:
  Apply all migrations: crud
Running migrations:
  Applying crud.0001_initial...Traceback (most recent call last):
  File "manage.py", line 18, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 161, in handle
    executor.migrate(targets, plan, fake=options.get("fake", False))
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 68, in migrate
    self.apply_migration(migration, fake=fake)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 102, in apply_migration
    migration.apply(project_state, schema_editor)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/migration.py", line 108, in apply
    operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/operations/models.py", line 36, in database_forwards
    schema_editor.create_model(model)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/schema.py", line 262, in create_model
    self.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/schema.py", line 103, in execute
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 82, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 66, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 66, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "crud_crudpermission" already exists

Some highlights from the migration file:

迁移文件中的一些亮点:

dependencies = [
    ('auth', '0001_initial'),
    ('contenttypes', '0001_initial'),
]
    migrations.CreateModel(
        name='CrudPermission',
        fields=[
            ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
            ('_created_by', models.CharField(default=b'', max_length=64, null=True, editable=False, blank=True)),
            ('_last_updated_by', models.CharField(default=b'', max_length=64, null=True, editable=False, blank=True)),
            ('_created', models.DateTimeField(null=True, editable=False, blank=True)),
            ('_last_updated', models.DateTimeField(null=True, editable=False, blank=True)),
            ('domain', models.CharField(max_length=32, choices=[(b'town', b'Town'), (b'boe', b'BOE'), (b'police', b'Police')])),
            ('ldap_group', models.CharField(max_length=128, verbose_name=b'LDAP group')),
            ('can_add', models.BooleanField(default=False, verbose_name=b'add')),
            ('can_change', models.BooleanField(default=False, verbose_name=b'change')),
            ('restrict_change_to_own', models.BooleanField(default=False)),
            ('can_delete', models.BooleanField(default=False, verbose_name=b'delete')),
            ('restrict_delete_to_own', models.BooleanField(default=False)),
            ('models', models.ManyToManyField(to='contenttypes.ContentType', null=True, blank=True)),
        ],
        options={
            'verbose_name': 'CRUD permission',
        },
        bases=(models.Model,),
    ),
    migrations.AlterUniqueTogether(
        name='crudpermission',
        unique_together=set([('ldap_group', 'can_add', 'can_change', 'can_delete', 'domain')]),
    )

,

,

The crud app is not meant to actually do anything, but I use it another app, so when I try migrate from that app, I trigger the above problem.

crud 应用程序实际上并不打算做任何事情,但我将它用作另一个应用程序,因此当我尝试从该应用程序迁移时,我触发了上述问题。

I've found other examples on the web of people with similar issues, but none of their cases seem to apply because

我在网上找到了其他有类似问题的人的例子,但他们的案例似乎都不适用,因为

  1. The problem affects an entire relation, not just one column
  2. I am not using multiple inheritance.
  1. 该问题影响整个关系,而不仅仅是一列
  2. 我没有使用多重继承。

Where should I look next to find the underlying problem?

接下来我应该在哪里寻找潜在的问题?

回答by Rickka

Been facing a similar issue, eventually deleted all .py files in migration folder (django 1.7 creates one automatically), worked perfectly after that.

遇到了类似的问题,最终删除了迁移文件夹中的所有 .py 文件(django 1.7 自动创建了一个),之后完美运行。

回答by trex

This works pretty fine

这很好用

./manage.py migrate --fake default

Source: -https://github.com/nijel/weblate/issues/587

来源: - https://github.com/nijel/weblate/issues/587

回答by Mudassar Hashmi

Do python manage.py migrate --fakeinitally.

一开始就做python manage.py migrate --fake

Read https://docs.djangoproject.com/en/1.9/ref/django-admin/#django-admin-migrate

阅读https://docs.djangoproject.com/en/1.9/ref/django-admin/#django-admin-migrate

回答by roboslone

I've faced similar issue when added couple new fields to existing model. I'm using Django 1.9, which introduced--run-syncdboption. Running manage.py migrate --run-syncdbfixed my tables.

在向现有模型添加几个新字段时,我遇到了类似的问题。我正在使用 Django 1.9,它引入了--run-syncdb选项。跑步manage.py migrate --run-syncdb修好了我的桌子。

回答by Shaun Kruger

I found and solved a particular example of this error in a Django 1.10 project while I was changing a foreign key field named memberto point to a different table. I was changing this in three different models and I hit this error on all of them. In my first attempt I renamed memberto member_userand tried to create a new field memberas a foreign key pointing at the new table, but this didn't work.

我在 Django 1.10 项目中发现并解决了此错误的一个特定示例,当时我正在更改名为member指向不同表的外键字段。我在三个不同的模型中改变了这个,我在所有模型上都遇到了这个错误。在我的第一次尝试中,我重命名membermember_user并尝试创建一个新字段member作为指向新表的外键,但这不起作用。

What I found is that when I renamed the membercolumn it did not modify the index name in the form <app>_<model>_<hash>and when I tried to create a new membercolumn it tried to create the same index name because the hash portion of the name was the same.

我发现当我重命名member列时,它没有修改表单中的索引名称<app>_<model>_<hash>,当我尝试创建一个新member列时,它尝试创建相同的索引名称,因为名称的哈希部分是相同的。

I resolved the problem by creating a new member_userrelation temporarily and copying the data. This created a new index with a different hash. I then deleted memberand recreated it pointing at the new table and with it the would-be conflicting index name. Once that was done I ran the RunPythonstep to populate the new membercolumn with references to the applicable table. I finished by adding RemoveFieldmigrations to clean up the temporary member_usercolumns.

我通过member_user临时创建一个新关系并复制数据解决了这个问题。这创建了一个具有不同哈希值的新索引。然后我删除member并重新创建它指向新表,并使用它可能会冲突的索引名称。完成后,我运行了使用对适用表的引用RunPython填充新member列的步骤。我通过添加RemoveField迁移来清理临时member_user列来完成。

I did have to split my migrations into two files because I received this error:

我确实不得不将我的迁移分成两个文件,因为我收到了这个错误:

psycopg2.OperationalError: cannot ALTER TABLE "<table_name>" because it has pending trigger events

psycopg2.OperationalError: 无法 ALTER TABLE "<table_name>" 因为它有挂起的触发事件

After the creation and copy of data into member_userI was not able to remove memberin the same migration transaction. This may be a postgres specific limitation, but it was easily resolved by creating another transaction and moving everything after creating and copying member_userinto the second migration.

在创建和复制数据后,member_user我无法member在同一个迁移事务中删除。这可能是 postgres 特定的限制,但可以通过创建另一个事务并在创建并复制member_user到第二次迁移后移动所有内容来轻松解决。

回答by Raydel Miranda

Now (I'm using Django 1.9) you can make:

现在(我使用的是 Django 1.9)你可以:

./manage.py [--database DATABASE] --fake [app_label] [migration_name]

./manage.py [--database DATABASE] --fake [app_label] [migration_name]

This way you're targeting the problem with more accuracy, and you can fake only the problematic migration on the specific database.

通过这种方式,您可以更准确地定位问题,并且可以仅伪造特定数据库上有问题的迁移。

So, looking at the question, you could:

所以,看看这个问题,你可以:

./manage.py --database default --fake crud crud.0001_initial

./manage.py --database 默认 --fake crud crud.0001_initial

回答by Vishal Mopari

I was facing the similar issues, where i had changed column name. I was getting same error as mentioned in the stack-trace provided with he question.

我遇到了类似的问题,我更改了列名。我遇到了与他问题提供的堆栈跟踪中提到的相同的错误。

Here's what I did.

这就是我所做的。

I ran fake migrations first. Then i removed it's(migrations i wanted to run) entry from django_migrationstable and ran migrations again(no fake this time).

我首先运行了假迁移。然后我从django_migrations表中删除了它的(我想运行的迁移)条目并再次运行迁移(这次不是假的)。

Changes appeared as expected for me.

变化出现在我的预期中。

hope this is helpful.

希望这是有帮助的。

回答by R.kiani

I found this problem in web2pyframeworkin models/config.py.

web2pyframeworkmodels/config.py.

Change

改变

settings.base.migrate = True

settings.base.migrate = True

on config file to

在配置文件上

settings.base.migrate = False

settings.base.migrate = False

Problem solved.

问题解决了。

回答by theeastcoastwest

Django provides a --fake-initialoption which I found effective for my use. From the Django Migration Documentation:

Django 提供了一个--fake-initial我发现对我有用的选项。来自Django 迁移文档

--fake-initial

Allows Django to skip an app's initial migration if all database tables with the names of all models created by all CreateModel operations in that migration already exist. This option is intended for use when first running migrations against a database that preexisted the use of migrations. This option does not, however, check for matching database schema beyond matching table names and so is only safe to use if you are confident that your existing schema matches what is recorded in your initial migration.

--fake-initial

如果迁移中的所有 CreateModel 操作创建的具有所有模型名称的所有数据库表已经存在,则允许 Django 跳过应用程序的初始迁移。此选项旨在在首次针对预先存在使用迁移的数据库运行迁移时使用。但是,此选项不会检查匹配表名称之外的匹配数据库架构,因此只有在您确信现有架构与初始迁移中记录的架构匹配时才可以安全使用。

For my use, I had just pulled a project from version control and was preparing to add some new model fields. I added the fields, ran ./manage.py makemigrationsand then attempted to run ./manage.py migratewhich threw the error since, as one would expect, many of the fields already existed in the existing database.

对于我的使用,我刚刚从版本控制中提取了一个项目,并准备添加一些新的模型字段。我添加了字段,./manage.py makemigrations然后运行,然后尝试运行./manage.py migrate,这引发了错误,因为正如人们所料,现有数据库中已经存在许多字段。

What I should have done was to run makemigrationsimmediately after pulling the project from versions control to create a snapshot of existing models' state. Then, running the ./manage.py migrate --fake-initialwould be the next step.

我应该做的是makemigrations在从版本控制中提取项目后立即运行以创建现有模型状态的快照。然后,运行./manage.py migrate --fake-initial将是下一步。

After that you can add away and makemigrations> migrateas normal.

之后,您可以正常添加和makemigrations> migrate

NOTE:I do not know if a --fake-initialwould skip existing fields andadd new ones. I opted to comment out the new fields I'd created up to that point, run the --fake-initialas if it were the first thing I did after pulling from version control, thenadded in updated fields in the next migration.

注意:我不知道 a--fake-initial是否会跳过现有字段添加新字段。我选择注释掉到目前为止我创建的新字段,--fake-initial就像我从版本控制中提取后所做的第一件事一样运行它,然后在下一次迁移中添加到更新的字段中。

Other related documentation: https://docs.djangoproject.com/en/dev/topics/migrations/#initial-migrations

其他相关文档:https: //docs.djangoproject.com/en/dev/topics/migrations/#initial-migrations

回答by max

I've been dealing with this for several years. There could be different scenarios:

我处理这个问题已经好几年了。可能有不同的场景:

Scenario 1: as in the original post, you had no tables to start with. In this case, I'd

场景 1:如在原始帖子中一样,您没有可以开始使用的表格。在这种情况下,我会

  1. comment out the relationship in models.py
  2. run python manage.py
  3. migrate assuming that it now succeeds
  4. uncomment what you
  5. commented out in step 1 run python manage.py migrate --fake
  1. 注释掉models.py中的关系
  2. 运行 python manage.py
  3. 迁移假设它现在成功
  4. 取消对你的评论
  5. 在步骤 1 中注释掉运行 python manage.py migrate --fake

Scenario 2: multiple apps: One possibility is that you might have different apps and the data model of one app is using some tables from the other app. In this case, if the data model is designed properly, you should be able to create the tables for one app only (by specifying only that one in setting.py), then add the other app and migrate. If it is not design with care, and there are recursive dependencies, I suggest changing the design rather than making a temporary fix.

场景 2:多个应用程序:一种可能性是您可能有不同的应用程序,并且一个应用程序的数据模型正在使用另一个应用程序的一些表。在这种情况下,如果数据模型设计正确,您应该能够仅为一个应用程序创建表(通过在 setting.py 中仅指定该表),然后添加另一个应用程序并迁移。如果不是精心设计,并且存在递归依赖关系,我建议更改设计而不是临时修复。

Scenario 3: you had some tables and something went wrong with your migration, then I'd

场景 3:你有一些表,你的迁移出了问题,然后我会

  1. revert models.py to what it was and only introduce the new relationship that appears to already exist in models.py.
  2. delete migration folder
  3. run python manage.py makemigrations
  4. introduce new changes to models.py if any and continue with makemigrations and migrate commands as usual.
  1. 将models.py恢复到原来的样子,只引入models.py中似乎已经存在的新关系。
  2. 删除迁移文件夹
  3. 运行 python manage.py makemigrations
  4. 如果有的话,向models.py 引入新的更改,并像往常一样继续执行makemigrations 和migrate 命令。