如何在SQLAlchemy中增加一个计数器

时间:2010-02-25 14:48:57

标签: python sqlalchemy

假设我的表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。

3 个答案:

答案 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)

我在这里遵循FastAPISQLAlchemydatabases(异步)的教程。经过各种尝试,我终于在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)
)