2014-12-09 3 views
5

Considerate questo struttura:Cambiare tipo di colonna con le migrazioni Django

some_table(id: small int) 

e voglio cambiarlo a questo:

some_table(id: string) 

Ora faccio questo con tre migrazioni:

  1. Crea una nuova colonna _id con tipo stringa
  2. (datamigratio n) Copiare i dati dalla id a _id con conversione di stringhe
  3. Rimuovere id e rinominare _id a id

C'è un modo per fare questo con una sola migrazione?

risposta

7

È possibile modificare direttamente il tipo di una colonna da int a stringa. Nota che, a meno che la modalità sql ristretta non sia abilitata, gli interi saranno troncati alla lunghezza massima della stringa e i dati potrebbero andare persi, quindi fai sempre un backup e scegli uno max_length che sia abbastanza alto. Inoltre, la migrazione non può essere facilmente annullata (sql non supporta direttamente la modifica di una colonna di stringhe in una colonna int), quindi un backup è davvero importante in questo.

Django pre 1.7/Sud

È possibile utilizzare db.alter_column. In primo luogo, creare una migrazione, ma non si applicano ancora, o perderai i dati:

>>> python manage.py schemamigration my_app --auto 

Quindi, cambiare il metodo di forwards in questo:

class Migration(SchemaMigration): 
    def forwards(self, orm): 
     db.alter_column('some_table', 'id', models.CharField(max_length=255)) 

    def backwards(self, orm): 
     raise RuntimeError('Cannot reverse this migration.') 

Ciò modificherà la colonna per abbinare il nuovo campo CharField. Ora applica la migrazione e il gioco è fatto.

Django 1.7 È possibile utilizzare l'operazione AlterField per cambiare la colonna. In primo luogo, creare una migrazione vuota:

>>> python manage.py makemigrations --empty my_app 

Quindi, aggiungere la seguente operazione:

class Migration(migrations.Migration): 
    operations = [ 
     migrations.AlterField('some_model', 'id', models.CharField(max_length=255)) 
    ] 

Ora eseguire la migrazione e Django altererà il campo in base al nuovo CharField.