2012-04-03 16 views
8

Io uso sud per migrare i miei modelli di Django. C'è tuttavia un brutto insetto nel sud. Non imposta valori predefiniti nei database Postgres. Esempio:migrazione django sud, non imposta default

created_at = models.DateTimeField(default = datetime.now) 
tag_id = models.PositiveIntegerField(default = 0) 

Sud aggiungerà questi 2 campi al database, ma non riescono a impostare i valori di default, che deve essere fatto manualmente.

C'è qualche patch per questo bug?

UPDATE avevo già provato a fissare la data di default con auto_now_add=True, ma che non sia anche l'impostazione di default. L'aggiunta di null=True nel campo aggiunge uno db.alter_column nello script di migrazione prodotto da sud. Ma questo solo rimuove il vincolo NOT NULL, non aggiunge un valore predefinito. Lo stesso vale per il campo intero

risposta

11

Questo non è un bug, in Sud o altrove.

Penso che tu sia confuso su come i valori predefiniti funzionino in genere in Django. Django non imposta valori predefiniti nello schema del database. Li applica direttamente in Python, quando viene creata una nuova istanza. È possibile verificare ciò facendo manage.py sqlall e verificare che l'SQL generato non contenga gli attributi default.

+2

Come imporre un valore predefinito nel database Postgres. Ho delle API che negoziano direttamente con il database creato da Django. Si aspettano che i valori predefiniti siano a posto. – jerrymouse

+5

Dovrai usare l'SQL personalizzato per modificare te stesso lo schema. Puoi farlo in Sud passando l'SQL a ['db.execute'] (http://south.aeracode.org/docs/databaseapi.html#db-execute). –

+3

Daniel solo perché Django cerca di impedire agli utenti di modificare le impostazioni predefinite del campo a livello di schema, ciò non significa che NON DEVONO essere in grado di farlo. Ho pubblicato una soluzione reale di seguito. – galarant

21

Se si sta auto-generando i tuoi migrazioni utilizzando:

./manage.py schemamigration app_name --auto 

allora avete bisogno di fare una piccola modifica alla migrazione prima che realmente applicarlo. Andate in migrazione generato (dovrebbe essere chiamato qualcosa come app_name/migrazioni/000X__auto_add_field_foo.py) e cercare l'argomento:

keep_default=False 

nella chiamata db.add_column. Semplicemente cambiare questo:

keep_default=True 

E Django verranno ora applicate valore predefinito per lo schema attuale, in aggiunta a qualsiasi righe esistenti. Sarebbe bello se South avesse un qualche tipo di impostazione per generare questo parametro come True di default, ma non così fortunato. Dovrai apportare questa modifica ogni volta.

+0

+1 Molto più semplice della scrittura di SQL personalizzato –

+5

+1. Sfortunatamente ['keep_default' è deprecato in Sud 0.8.1] (http://south.readthedocs.org/en/latest/releasenotes/0.8.1.html#keep-default-fully-deprecated) – Pankrat

+0

dannazione, Pankrat ha ragione ... – galarant

2

Come menzionato nelle risposte precedenti, il meccanismo predefinito in django è implementato nella classe del modello e non è rilevante per le migrazioni del sud.

Inoltre, dal sud 0.8, the keep_default flag is deprecated, e non aggiungerà il valore predefinito al modello.

Quello che faccio per risolvere questo è scrivere una migrazione personalizzata per aggiungere il valore predefinito. Si può fare con la creazione di un separato data migration:

./manage.py datamigration your_app_name migration_name 

e aggiungere la seguente riga alla funzione forwards:

orm.YourModel.objects.update(field_name = DEFAULT_VALUE) 

In alternativa, invece di creare una nuova migrazione, è possibile modificare la migrazione originale:

  1. aggiungere no_dry_run = True alla classe stessa (in modo da poter accedere all'ORM).
  2. aggiungere orm.YourModel.objects.update(field_name = DEFAULT_VALUE) alla fine della funzione forwards.

In questo modo non è necessario scrivere una migrazione all'indietro, poiché si dispone già della colonna di eliminazione originale.

Problemi correlati