2011-08-17 8 views
6

¿me puede ayudar a entender por qué este código causa una entrada duplicada (IntegrityError)?Django - get_or_create no funciona

Estoy en Django 1.2.

(row, is_new) = MyModel.objects.get_or_create(field1=1) 
row.other_field = 2 
row.save() 

Tengo una restricción única en el campo1. Si hay una fila donde campo1 = 1, todo funciona bien, Django hace un "obtener".

Si no hay una fila donde campo1 = 1, parece que Django está creando esa fila que está bien. Pero ¿por qué no me deja guardarlo?

Actualización:

Si ayuda, aquí es MyModel:

class MyModel(models.Model): 
    id = models.BigIntegerField(primary_key=True) 
    field1 = models.BigIntegerField(unique=True) 
    other_field = models.CharField(max_length=765) 
    class Meta: 
     db_table = u'project_crosses_suppl_FO' 

campo1 es una clave externa a otra tabla. Pero no hice una maqueta en Django para esa mesa, así que no le digo a Django que es una clave foránea.

+0

¿El MyModel tiene campo extranjero? ¿Puedes publicar el código de MyModel? –

+1

[Esta pregunta similar] (http://stackoverflow.com/questions/6974463/django-get-or-create-raises-duplicate-entry-with-together-unique) podría ayudarlo. – agf

+0

@agf. No entiendo cuál era la resolución en esa pregunta o cómo se justifica el problema. Suena como un error para mí. Creo que me rendiré en get_or_create y lo solucionaré :-( – Greg

Respuesta

3

get_or_create me suenan los bustos. Sólo estoy haciendo este trabajo en torno a:

rows = MyModel.objects.filter(field1=1) 
row = rows[0] if rows else MyModel(field1=1) 
row.other_field = 2 
row.save() 
7

Si se asume que es una representación bastante fiel de su código real, no es sorprendente que no se Django eso está roto, es su modelo.

Ha anulado el campo de la clave primaria automática con su propio campo id, pero no ha hecho una autoincrementación. Entonces, la base de datos no usa un nuevo valor para PK, de ahí el error de integridad.

A menos que tengas una buena razón, deberías dejar que Django se ocupe del campo PK.

+1

Oh, ese es un buen punto. Es una tabla existente que no puedo cambiar. Eso es ¿Por qué le digo a Django cuál es la clave principal? Entonces, ¿qué cambio exactamente? La columna "id" en la tabla MySQL está configurada para autoincrementarse. ¿Debo decirle a Django que es un campo de incremento automático? – Greg

+0

@Greg, ¿Ya has probado esto? – Kirill

1

Obtener o Crear devuelve una tupla de resultados, incluso si el campo que utiliza está configurado como clave principal o único.

Así, en su caso: fila es una tupla con un objeto, por lo tanto, esto debería funcionar para usted:

(row, is_new) = MyModel.objects.get_or_create(field1=1) 
row[0].other_field = 2 
row[0].save() 
Cuestiones relacionadas