django.db.utils.ProgrammingError: la relación ya existe

Estoy tratando de configurar las tablas para un nuevo proyecto de django (es decir, las tablas NO existen en la base de datos); la versión de django es 1.7 y el back-end de la base de datos es PostgreSQL. El nombre del proyecto es crud. Los resultados del bash de migración son los siguientes:

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

 Operations to perform: Apply all migrations: crud Running migrations: Applying crud.0001_initial...Traceback (most recent call last): File "manage.py", line 18, in  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 

Algunos aspectos destacados del archivo de migración:

 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')]), ) 

,

La aplicación crud no está destinada a hacer nada en realidad, pero la uso en otra aplicación, así que cuando bash migrar desde esa aplicación, desencadeno el problema anterior.

He encontrado otros ejemplos en la web de personas con problemas similares, pero ninguno de sus casos parece aplicarse porque

  1. El problema afecta a una relación completa, no solo a una columna
  2. No estoy usando herencia múltiple.

¿Dónde debo buscar a continuación para encontrar el problema subyacente?

Esto funciona bastante bien

 ./manage.py migrate --fake default 

Fuente: – https://github.com/nijel/weblate/issues/587

Haga python manage.py migrate --fake –fake inicialmente.

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

Ante un problema similar, eventualmente eliminó todos los archivos .py en la carpeta de migración (django 1.7 crea uno automáticamente), después de eso funcionó perfectamente.

He enfrentado problemas similares cuando agregué nuevos campos al modelo existente. Estoy usando Django 1.9, que introdujo la opción --run-syncdb . Ejecutar manage.py migrate --run-syncdb corrigió mis tablas.

Me enfrentaba a problemas similares, donde había cambiado el nombre de la columna. Recibí el mismo error que se menciona en el seguimiento de stack provisto con la pregunta.

Esto es lo que hice.

Primero corrí migraciones falsas. Luego eliminé su entrada (migraciones que quería ejecutar) de la tabla django_migrations y ejecuté migraciones nuevamente (no es falso esta vez).

Los cambios aparecieron como se esperaba para mí.

Espero que esto sea de ayuda.

Ahora (estoy usando Django 1.9) puedes hacer:

./manage.py [–Database DATABASE] –fake [app_label] [migration_name]

De esta manera, está enfocando el problema con mayor precisión y puede falsificar solo la migración problemática en la base de datos específica.

Entonces, mirando la pregunta, podrías:

./manage.py – predeterminado de la base de datos –fake crud crud.0001_initial

Django prueba una opción --fake-initial que encontré efectiva para mi uso. De la Documentación de Migración Django :

–fake-initial

Permite a Django omitir la migración inicial de una aplicación si ya existen todas las tablas de base de datos con los nombres de todos los modelos creados por todas las operaciones de CreateModel en esa migración. Esta opción está diseñada para ser utilizada cuando se ejecutan migraciones por primera vez en una base de datos que preexistía el uso de migraciones. Sin embargo, esta opción no busca el esquema de base de datos coincidente más allá de los nombres de tabla coincidentes, por lo que solo es seguro de usar si está seguro de que su esquema existente coincide con lo que se registró en su migración inicial.

Para mi uso, acababa de sacar un proyecto del control de versiones y me estaba preparando para agregar algunos nuevos campos de modelo. ./manage.py makemigrations los campos, ejecuté ./manage.py makemigrations y luego intenté ejecutar ./manage.py migrate que ./manage.py migrate el error ya que, como era de esperar, muchos de los campos ya existían en la base de datos existente.

Lo que debería haber hecho fue ejecutar makemigrations inmediatamente después de extraer el proyecto del control de versiones para crear una instantánea del estado de los modelos existentes. Luego, ejecutar el ./manage.py migrate --fake-initial sería el siguiente paso.

Después de eso, puede agregar y makemigrations > migrate forma normal.

NOTA: No sé si un --fake-initial omitirá los campos existentes y agregará nuevos. Opté por comentar los nuevos campos que había creado hasta ese momento, ejecutar el --fake-initial como si fuera lo primero que hice después de salir del control de versiones, y luego agregarlo en los campos actualizados en la próxima migración.

Otra documentación relacionada: https://docs.djangoproject.com/en/dev/topics/migrations/#initial-migrations

Encontré y resolví un ejemplo particular de este error en un proyecto Django 1.10 mientras estaba cambiando un campo de clave externa llamado member para apuntar a una tabla diferente. Estaba cambiando esto en tres modelos diferentes y cometí este error en todos ellos. En mi primer bash member member_user nombre de member a member_user e intenté crear un nuevo member campo como una clave externa que apunta a la nueva tabla, pero esto no funcionó.

Lo que encontré es que cuando renombré la columna member , no modificó el nombre del índice en la forma __ y cuando intenté crear una nueva columna member , trató de crear el mismo nombre de índice porque la porción de hash del nombre era la misma.

member_user el problema creando una nueva relación de member_user temporalmente y copiando los datos. Esto creó un nuevo índice con un hash diferente. Luego eliminé el member y lo volví a crear apuntando a la nueva tabla y con él el posible nombre del índice en conflicto. Una vez hecho esto, ejecuté el paso RunPython para rellenar la nueva columna de member con referencias a la tabla correspondiente. Terminé agregando migraciones de RemoveField para limpiar las columnas de member_user temporales.

Tuve que dividir mis migraciones en dos archivos porque recibí este error:

psycopg2.OperationalError: no se puede ALTER TABLE “” porque tiene eventos desencadenantes pendientes

Después de la creación y copia de los datos en member_user , no pude eliminar el member en la misma transacción de migración. Esto puede ser una limitación específica de Postgres, pero se resolvió fácilmente creando otra transacción y moviendo todo después de crear y copiar member_user en la segunda migración.

Encontré este problema en web2pyframework en models/config.py .

Cambio

settings.base.migrate = True

en el archivo de configuración para

settings.base.migrate = False

Problema resuelto.