2011-08-18 9 views
11

la documentazione di Django è abbastanza chiara su come conservare le stringhe vuote come "" piuttosto che NULL a livello di database (per cui v'è solo una possibile formato per i dati vuoti):Django ORM, CharField e vuoto = True

Nota i valori di stringa vuoti verranno sempre memorizzati come stringhe vuote, non come NULL. Usa null = True solo per i campi non stringa come interi, booleani e date. Per entrambi i tipi di campi, dovrai anche impostare blank = True se desideri consentire valori vuoti nei moduli, poiché il parametro null influisce solo sull'archiviazione del database (vedi vuoto).

Tuttavia, dopo aver aggiunto un nuovo campo, ho iniziato a incontrare IntegrityErrors sul nuovo campo (numero di telefono).

valore nullo nella colonna "phone_number" viola vincolo non nullo

Quel modello si presenta così con il nuovo campo (ho eseguito una migrazione tramite sud):

class Person(models.Model): 
    user = models.ForeignKey(User) 
    description = models.TextField(blank=True) 
    phone_number = models.CharField(blank=True) 

I da quando (temporaneamente) risolto il problema impostando null = True su phone_number, ora ho centinaia di voci con stringhe vuote e un singolo valore NULL nel mio database. (Ho anche provato ad aggiungere default = '' al campo phone_number, ma stavo ancora vedendo i problemi di IntegrityError.)

In passato ho sempre usato MySQL, ma su questo progetto sto usando Postgres. Il tentativo di inserimento SQL generato è:

'INSERT INTO "people_person" ("user_id", "description", "gender", "birthdate", "default_image_id", "zip_code", "beta_status") VALUES (%s, %s, %s, %s, %s, %s, %s) RETURNING "people_person"."id"'.

La mia aspettativa sarebbe che Django inserisse una stringa vuota nella colonna "phone_number", ma non sembra che lo stia facendo. L'altra cosa che potrei aspettarmi sarebbe che Django includa un SET DEFAULT nell'istruzione CREATE TABLE, ma non lo fa. Così Postgres si arrabbia per il NOT NULL su quella colonna.

Grazie!

risposta

7

Come di solito è il caso di problemi che sono così apparentemente intrattabili, il problema era l'errore dell'utente.

La mia applicazione aveva due punti di accesso: due file WSGI, ma solo un codice base. Normalmente, Apache ricaricherà il tuo codice solo se il file viene toccato. Il mio script di implementazione stava solo toccando uno di quei file WSGI - il che significava che le persone che raggiungevano il mio sito tramite l'altro file WSGI continuavano a vedere il vecchio codice. Peggio ancora, il database è stato modificato con quel vecchio codice, ma i modelli erano ancora come erano prima.

Questo a sua volta ha causato i problemi IntegrityError. Django non sapeva del campo phone_number, quindi, anche se avevo impostato blank=True, Django non ha fatto alcuno sforzo per inserire un valore vuoto - e il database ovviamente pensava che significasse NULL.

Ciò ha causato una serie di errori di tracciamento diversi tra cui l'errore precedente.

È incredibile quanto spesso problemi davvero difficili come questi siano causati da piccole omissioni stupide, come uno script di distribuzione che ho scritto 2 mesi fa e che ho dimenticato di aggiornare.

Grazie per aver letto la gente, ho svalutato le altre risposte, ma ho bisogno di accettare il mio poiché alla fine era la soluzione.

6

Ho scoperto che se si imposta esplicitamente il valore del campo su None si otterranno ancora questi errori. In altre parole, la cosa default= viene applicata non appena si crea l'oggetto python, piuttosto quando lo si salva nel database.

Immagino che sia ragionevole ma è stato un po 'inaspettato.

+0

la stessa cosa sembra accadere se si passa un 'None' al costruttore (quindi, alla creazione) –

Problemi correlati