2011-08-18 13 views
11

documentación de Django es bastante claro sobre el almacenamiento de las cadenas vacías como "" en lugar de NULL a un nivel de base de datos (lo que sólo hay un posible formato para los datos vacías):ORM de Django, CharField y blanco = True

Nota que los valores de cadena vacíos siempre se almacenarán como cadenas vacías, no como NULL. Solo use null = True para campos que no sean cadenas como enteros, booleanos y fechas. Para ambos tipos de campos, también deberá establecer en blanco = Verdadero si desea permitir valores vacíos en formularios, ya que el parámetro nulo solo afecta el almacenamiento de la base de datos (ver en blanco).

Sin embargo, después de agregar un nuevo campo, he comenzado a encontrar IntegrityErrors en el campo nuevo (phone_number).

valor nulo en la columna "phone_number" viola la restricción no nula

Ese modelo se parece a esto con el nuevo campo (He realizado una migración a través sur):

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

I Desde entonces (temporalmente) resolvió el problema al establecer null = True en phone_number, pero ahora tengo cientos de entradas con cadenas vacías y un único valor NULL en mi base de datos. (También intenté agregar default = '' al campo phone_number, pero todavía estaba viendo problemas de IntegrityError.)

En el pasado siempre he usado MySQL, pero en este proyecto estoy usando Postgres. El intento de inserción de SQL generado es:

'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"'.

Mi expectativa sería que Django estaría insertando una cadena en blanco en la columna "phone_number", pero no parece estar haciéndolo. La otra cosa que podría esperar sería que Django incluyera un SET DEFAULT en la declaración CREATE TABLE, pero no es así. Entonces Postgres se enoja por el NOT NULL en esa columna.

Gracias!

Respuesta

7

Como suele ser el caso con problemas que son aparentemente intratables, el problema fue el error del usuario.

Mi aplicación tenía dos puntos de entrada: dos archivos WSGI, pero solo una base de código. Normalmente, Apache solo volverá a cargar tu código si se toca el archivo. Mi script de implementación solo estaba tocando uno de esos archivos WSGI, lo que significaba que las personas que llegaban a mi sitio a través del otro archivo WSGI seguían viendo el código anterior. Peor aún, la base de datos se modificó con ese código anterior, pero los modelos seguían igual que antes.

Esto a su vez causó los problemas IntegrityError. Django no sabía sobre el campo phone_number, así que aunque yo había establecido blank=True, Django no hizo ningún esfuerzo por insertar un valor en blanco, y la base de datos, por supuesto, pensó que significaba NULO.

Esto provocó una serie de errores de localización diferentes, incluido el error anterior.

Es increíble la frecuencia con la que las cuestiones realmente difíciles como estas son causadas por omisiones menores tontas, como una secuencia de comandos de implementación que escribí hace 2 meses y olvidé actualizar.

Gracias por leer amigos, he votado las otras respuestas, pero tengo que aceptar la mía ya que finalmente fue la solución.

6

Descubrí que si establece explícitamente el valor de campo en None, seguirá recibiendo estos errores. En otras palabras, la cosa default= se aplica tan pronto como se crea el objeto python, en lugar de guardarlo en la base de datos.

Supongo que es razonable, pero fue un poco inesperado.

+0

Lo mismo parece suceder si pasa un 'Ninguno' al constructor (por lo tanto, en la creación) –

Cuestiones relacionadas