如何在SQLAlchemy中增加计数器
假设我有一个叫做 tags
的表,这个表里有一个字段 count
,它表示有多少个 items
被标记了这个标签。
那么在我添加一个带有已有标签的新项目后,如何在 SQLAlchemy 中增加这个计数呢?
如果用普通的 SQL,我会这样做:
INSERT INTO `items` VALUES (...)
UPDATE `tags` SET count=count+1 WHERE tag_id=5
但是我该如何在 SQLAlchemy 中表示 count=count+1
呢?
3 个回答
1
关于@Leon的评论,你可以稍微改写一下代码,以避免竞争条件。
async def inc_counter(id_: int):
query = items.update(items.c.id==id_)
return await db.execute(query, values={'counter': items.c.counter + 1})
另外,如果你是以类的方式创建表格,你需要访问table这个属性:
from sqlalchemy import update
async def inc_counter(id_: int):
query = update(Items).filter(Items.id==id_)
return await db.execute(query, values={'counter': Items.__table__.c.counter + 1})
55
如果你在使用SQL层,那么你可以在更新语句中使用任意的SQL表达式:
conn.execute(tags.update(tags.c.tag_id == 5).values(count=tags.c.count + 1))
ORM查询对象也有一个更新的方法:
session.query(Tag).filter_by(tag_id=5).update({'count': Tag.count + 1})
这个ORM版本很聪明,如果对象在会话中,它还会自动更新对象本身的计数属性。
94
如果你有类似这样的东西:
mytable = Table('mytable', db.metadata,
Column('id', db.Integer, primary_key=True),
Column('counter', db.Integer)
)
你可以像这样增加字段的值:
m = mytable.query.first()
m.counter = mytable.c.counter + 1
或者,如果你有一些映射的模型,你也可以这样写:
m = Model.query.first()
m.counter = Model.counter + 1
这两种写法都会返回你想要的SQL语句。但是,如果你不写列名,直接写 m.counter += 1
,那么新的值会在Python中计算(这可能会导致竞争条件的问题)。所以在这种计数器查询中,记得像上面两个例子那样总是包含列名。