Pregunta ¿Cómo cambiar el nombre de un campo de clave externa con Sur?


Cambiar el nombre de un charfield simple, etc. parece fácil (Django: ¿cómo cambiar el nombre de un campo modelo usando South?)

Sin embargo, cuando intento usar el mismo en un campo ForeignKey, aparece un error:

_mysql_exceptions.OperationalError: (1091, "Can't DROP '[new_fkey_field_name]'; check that column/key exists")

Que se deriva de la migración que intenta ejecutar el hacia atrás por alguna razón (como se evidencia en el rastro).

¿Algunas ideas?


13
2017-08-14 21:23


origen


Respuestas:


Actualización: con mysql-5.5.30-1.fc18.x86_64 y

MySQL-python==1.2.4
Django==1.4.2
South==0.7.6

los siguientes trabajos:

class Migration(SchemaMigration_:
    def forwards(self, orm):
        db.rename_column('app_model', 'old_id', 'new_id')
        db.alter_column('app_model', 'new_id',
                        self.gf('django.db.models.fields.related.ForeignKey')(
                            blank=True,
                            null=True,
                            to=orm['app.OtherModel']
                        ))

    def backwards(self, orm):
        db.rename_column('app_model', 'new_id', 'old_id')
        db.alter_column('app_model', 'old_id',
                        self.gf('django.db.models.fields.related.ForeignKey')(
                            blank=True,
                            null=True,
                            to=orm['app.OtherModel']
                        ))

Como comenta @Eloff, South no puede encontrar el FK original por razones desconocidas, pero no parece importar. No hay necesidad de una migración de datos (creo) ya que los valores de pk no deberían cambiar.

La especificación de campo (usando self.gf) se toma de las migraciones autogeneradas de South para la consistencia.


4
2018-03-14 17:49



Primero, necesita usar el nombre de la columna db, no el del modelo. Por ejemplo: foobar_id no foobar.

Luego debe eliminar las restricciones fk y volver a crearlas después de cambiar el nombre:

db.drop_foreign_key('app_model', 'old_id')
db.rename_column('app_model', 'old_id', 'new_id')
db.alter_column('app_model', 'new_id', models.ForeignKey(to=orm['app.OtherModel']))

Si tu fk es nulo, debes usarlo para cambiarlo a:

db.alter_column('app_model', 'new_id', models.ForeignKey(null=True, to=orm['app.OtherModel']))

24
2017-07-21 09:24



Los usuarios de MySQL deberían estar al tanto de este error en el sur, si es que todavía se aplica:

http://south.aeracode.org/ticket/697

La solución alternativa es realizar la migración en 3 pasos:

1) Agregar un nuevo campo

2) los datos migran los datos al nuevo campo

3) eliminar el campo viejo


11
2017-07-26 17:19



Al renombrar un ForeignKey, recuerda agregar _id al final del nombre del campo que usas en Django. P.ej.

db.rename_column('accounts_transaction', 'operator_id', 'responsible_id')

Y no

db.rename_column('accounts_transaction', 'operator', 'responsible')

Pero solo he probado esto en sqlite (que en realidad no tienen ALTER_TABLE en absoluto), así que no sé si realmente funcionará en mysql / postgres.


6
2017-10-24 16:56



Preguntas populares