python - not - django db utils programmingerror no existe la columna
django.db.utils.ProgrammingError: la relaciĆ³n ya existe (9)
Estoy tratando de configurar las tablas para un nuevo proyecto 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 db es PostgreSQL. El nombre del proyecto es cruel. Los resultados del intento 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 <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
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, por lo que cuando intento migrar desde esa aplicación, provoco el problema anterior.
He encontrado otros ejemplos en la web de personas con problemas similares, pero ninguno de sus casos parece aplicarse porque
- El problema afecta una relación completa, no solo una columna
- No estoy usando herencia múltiple.
¿Dónde debería mirar a continuación para encontrar el problema subyacente?
Ahora (estoy usando Django 1.9) puedes hacer:
./manage.py [- BASE DE DATOS de la base de datos] --fake [etiqueta_aplicación] [nombre_migración]
De esta manera, está enfocando el problema con mayor precisión, y solo puede simular la migración problemática en la base de datos específica.
Entonces, mirando la pregunta, podrías:
./manage.py --database default --fake crud crud.0001_initial
Al enfrentar un problema similar, eventualmente eliminé todos los archivos .py en la carpeta de migración (django 1.7 crea uno automáticamente), funcionó perfectamente después de eso.
Django proporciona una opción
--fake-initial
que encontré efectiva para mi uso.
De la
documentación de migración de Django
:
--fake-initial
Permite a Django omitir la migración inicial de una aplicación si todas las tablas de la base de datos con los nombres de todos los modelos creados por todas las operaciones CreateModel en esa migración ya existen. Esta opción está diseñada para usarse cuando se ejecutan migraciones por primera vez en una base de datos que ya existía previamente. Sin embargo, esta opción no verifica el esquema de base de datos coincidente más allá de los nombres de tabla coincidentes y, por lo tanto, solo es seguro de usar si está seguro de que su esquema existente coincide con lo que se registra en su migración inicial.
Para mi uso, acababa de extraer un proyecto del control de versiones y me estaba preparando para agregar algunos nuevos campos modelo.
./manage.py makemigrations
los campos, ejecuté
./manage.py makemigrations
y luego intenté ejecutar
./manage.py migrate
que arrojó 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 hacer
makemigrations
>
migrate
como de costumbre.
NOTA:
No sé si
--fake-initial
omitiría los campos existentes
y
agregaría otros nuevos.
Opté por comentar los nuevos campos que había creado hasta ese momento, ejecutar
--fake-initial
como si fuera lo primero que hice después de extraer del control de versiones, y
luego
agregué campos actualizados en la próxima migración.
Otra documentación relacionada: https://docs.djangoproject.com/en/dev/topics/migrations/#initial-migrations
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.
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 llegué a este error en todos ellos.
En mi primer intento
member
member_user
nombre de
member
a
member_user
e intenté crear un nuevo
member
campo como una clave externa que apuntaba a la nueva tabla, pero esto no funcionó.
Lo que encontré es que cuando cambié el nombre de la columna de
member
, no modificó el nombre del índice en la forma
<app>_<model>_<hash>
y cuando intenté crear una nueva columna de
member
, traté de crear el mismo nombre de índice porque la parte hash del nombre era la misma.
member_user
el problema creando una nueva relación
member_user
temporalmente y copiando los datos.
Esto creó un nuevo índice con un hash diferente.
Luego eliminé el
member
y lo recreé apuntando a la nueva tabla y con él el posible nombre de índice en conflicto.
Una vez hecho esto, ejecuté el paso
RunPython
para llenar la nueva columna de
member
con referencias a la tabla correspondiente.
Terminé agregando
RemoveField
migraciones
RemoveField
para limpiar las columnas temporales
member_user
.
Tuve que dividir mis migraciones en dos archivos porque recibí este error:
psycopg2.OperationalError: no se puede ALTERAR LA TABLA "<table_name>" porque tiene eventos desencadenantes pendientes
Después de la creación y copia de datos en
member_user
no pude eliminar a un
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.
Esto funciona bastante bien
./manage.py migrate --fake default
Hacer
python manage.py migrate --fake
--fake initally.
Lea https://docs.djangoproject.com/en/1.9/ref/django-admin/#django-admin-migrate
Me enfrentaba a problemas similares, donde había cambiado el nombre de la columna. Estaba recibiendo el mismo error que se menciona en el seguimiento de pila proporcionado con la pregunta.
Esto es lo que hice.
Primero realicé migraciones falsas. Luego eliminé su entrada (migraciones que quería ejecutar) de la tabla django_migrations y ejecuté las migraciones nuevamente (esta vez no es falso).
Los cambios aparecieron como se esperaba para mí.
Espero que esto sea útil.
Me he enfrentado a un problema similar cuando agregué un par de campos nuevos al modelo existente.
Estoy usando Django 1.9, que
introduced
opción
--run-syncdb
.
Ejecutar
manage.py migrate --run-syncdb
arregló mis tablas.