假设我的表tags
有一个字段count
,表示已使用给定标记标记了多少items
。
在添加带有现有标记的新项目后,如何在SQLAlchemy中增加此计数器?
使用纯SQL我会执行以下操作:
INSERT INTO `items` VALUES (...)
UPDATE `tags` SET count=count+1 WHERE tag_id=5
但是如何在SQLAlchemy中表达count=count+1
?
谢谢,Boda Cydo。
答案 0 :(得分:47)
如果你有类似的话:
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中计算(并且可能发生竞争条件)。因此,请始终在此类计数器查询中包含上述两个示例中显示的列。
的问候,
克里斯托弗
答案 1 :(得分:27)
如果您使用的是SQL层,则可以在update语句中使用任意SQL表达式:
conn.execute(tags.update(tags.c.tag_id == 5).values(count=tags.c.count + 1))
ORM Query对象也有一个更新方法:
session.query(Tag).filter_by(tag_id=5).update({'count': Tag.count + 1})
ORM版本非常智能,如果它在会话中,也会更新对象本身的count属性。
答案 2 :(得分:0)
我在这里遵循FastAPI,SQLAlchemy和databases(异步)的教程。经过各种尝试,我终于在crud.py /控制层中使用以下代码对其进行了处理。
async def inc_counter():
query = counters.select(counters.c.id==1)
current_val = await database.fetch_val(query=query, column=1)
query = counters.update().where(counters.c.id==1).values(counter=current_val+1).returning(counters.c.counter)
return await database.execute(query=query)
我的桌子看起来像这样:
counters = Table('counters', metadata,
Column('id', Integer, primary_key=True),
Column('counter', Integer)
)