2010-02-25 4 views
21

Supposons que j'ai la table tags qui a un champ count qui indique combien de items ont été tagués avec le tag donné.Comment faire pour augmenter un compteur dans SQLAlchemy

Comment puis-je augmenter ce compteur dans SQLAlchemy après avoir ajouté un nouvel élément avec un tag existant?

Avec SQL simple je faire ce qui suit:

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

Mais comment puis-je exprimer count=count+1 en SQLAlchemy?

Merci, Boda Cydo.

Répondre

34

Si vous avez quelque chose comme:

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

Vous pouvez incrémenter champs comme ceci:

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

Ou, si vous avez des modèles mis en correspondance, vous pouvez écrire alternativement:

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

Les deux versions renverront l'instruction SQL que vous avez demandée. Mais si vous n'incluez pas la colonne et que vous écrivez simplement m.counter += 1, alors la nouvelle valeur sera calculée en Python (et les conditions de course sont susceptibles de se produire). Donc, toujours inclure une colonne comme indiqué dans les deux exemples ci-dessus dans de telles requêtes de compteur.

Cordialement,
Christoph

+2

Merci. Mais pouvez-vous expliquer plus sur l'état de la course? Est-ce que je vous ai bien compris que la première version serait plus sûre que la seconde? – bodacydo

+1

Non. Les deux versions que je vous ai montrées sont exactement les mêmes (on utilise des objets mappés et les autres tables). Mais la troisième déclaration avec '+ =' donnerait 'SET counter = 4' au lieu de' SET counter = counter + 1'. Vous ne devriez donc pas utiliser la troisième version '+ ='. – tux21b

+0

Compris. Merci pour ton aide! – bodacydo

19

Si vous utilisez la couche SQL, vous pouvez utiliser des expressions SQL arbitraires dans la déclaration de mise à jour:

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

L'objet de requête ORM a également une méthode de mise à jour: La version ORM est assez intelligente pour mettre à jour également l'attribut count sur l'objet lui-même si c'est dans la session.

Questions connexes