2010-02-25 12 views
21

Supongamos que tengo la tabla tags que tiene un campo count que indica cuántos items han sido etiquetados con la etiqueta dada.Cómo aumentar un contador en SQLAlchemy

¿Cómo puedo aumentar este contador en SQLAlchemy después de agregar un nuevo elemento con una etiqueta existente?

Con SQL llanura que haría lo siguiente:

INSERT INTO `items` VALUES (...) 
UPDATE `tags` SET count=count+1 WHERE tag_id=5 

Pero ¿Cómo expreso count=count+1 en SQLAlchemy?

Gracias, Boda Cydo.

Respuesta

34

Si usted tiene algo así como:

mytable = Table('mytable', db.metadata, 
    Column('id', db.Integer, primary_key=True), 
    Column('counter', db.Integer) 
) 

Puede incrementar los campos de la siguiente manera:

m = mytable.query.first() 
m.counter = mytable.c.counter + 1 

O, si usted tiene algunos modelos asignadas, se puede escribir alternativamente:

m = Model.query.first() 
m.counter = Model.counter + 1 

Ambas versiones devolverán la instrucción sql que solicitó. Pero si no incluye la columna y solo escribe m.counter += 1, entonces el nuevo valor se calcularía en Python (y es probable que ocurran condiciones de carrera). Por lo tanto, siempre incluya una columna como se muestra en los dos ejemplos anteriores en dichas consultas de contador.

Saludos,
Christoph

+2

Gracias. ¿Pero puedes explicar más sobre la condición de la raza? ¿Te entendí correctamente que la primera versión sería más segura que la segunda? – bodacydo

+1

No. Ambas versiones que he mostrado son exactamente iguales (una usa objetos mapeados y las otras tablas). Pero el tercer enunciado con '+ =' daría como resultado 'SET counter = 4' en lugar de' SET counter = counter + 1'. Entonces no deberías usar la tercera versión '+ ='. – tux21b

+0

Entendido. ¡Gracias por ayudar! – bodacydo

19

Si está utilizando la capa de SQL, a continuación, puede utilizar expresiones SQL de su elección en la instrucción de actualización:

conn.execute(tags.update(tags.c.tag_id == 5).values(count=tags.c.count + 1)) 

El objeto ORM Consulta también tiene un método de actualización:

session.query(Tag).filter_by(tag_id=5).update({'count': Tag.count + 1}) 

la versión ORM es lo suficientemente inteligente como para actualizar también el atributo de conteo en el objeto en sí mismo si está en la sesión

Cuestiones relacionadas