2010-02-25 15 views
21

Angenommen, ich habe Tabelle tags, die ein Feld count hat, die angibt, wie viele items wurden mit dem angegebenen Tag getaggt.So erhöhen Sie einen Zähler in SQLAlchemy

Wie kann ich diesen Zähler in SQLAlchemy erhöhen, nachdem ich ein neues Element mit einem vorhandenen Tag hinzugefügt habe?

Mit Ebene SQL ich folgendes tun würde:

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

Aber wie ich ausdrücken count=count+1 in SQLAlchemy?

Danke, Boda Cydo.

Antwort

34

Wenn Sie so etwas wie:

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

Sie Felder wie folgt erhöhen können:

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

Oder, wenn Sie einige kartiert Modelle haben, können Sie schreiben alternativ:

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

Beide Versionen geben die von Ihnen angeforderte SQL-Anweisung zurück. Aber wenn Sie die Spalte nicht einschließen und nur schreiben m.counter += 1, dann würde der neue Wert in Python berechnet werden (und Race-Bedingungen werden wahrscheinlich passieren). Fügen Sie also in solchen Counter-Abfragen immer eine Spalte ein, wie in den beiden obigen Beispielen gezeigt.

Grüße,
Christoph

+2

Danke. Aber können Sie mehr über den Zustand der Rasse erklären? Habe ich dich richtig verstanden, dass die erste Version sicherer wäre als die zweite? – bodacydo

+1

Nein. Beide Versionen, die ich Ihnen gezeigt habe, sind genau gleich (man verwendet gemappte Objekte und die anderen Tabellen). Aber die dritte Anweisung mit '+ =' würde zu 'SET counter = 4' anstelle von 'SET counter = counter + 1' führen. Du solltest also nicht die dritte '+ =' Version benutzen. – tux21b

+0

Verstanden. Danke fürs Helfen! – bodacydo

19

Wenn Sie die SQL-Schicht verwenden, dann können Sie beliebigen SQL-Ausdrücke in der Update-Anweisung verwenden:

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

Das ORM Abfrage Objekt auch eine Update-Methode hat:

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

Die ORM-Version ist intelligent genug, um auch das Attribut count für das Objekt selbst zu aktualisieren wenn es in der Sitzung ist.

Verwandte Themen