How to increase a counter in SQLAlchemy

后端 未结 3 1165
后悔当初
后悔当初 2020-12-04 21:55

Suppose I have table tags which has a field count that indicates how many items have been tagged with the given tag.

How do I

相关标签:
3条回答
  • 2020-12-04 22:22

    I got here following a tutorial for FastAPI, SQLAlchemy and databases (async). After various tries I finally got it working with following code in my crud.py / control layer.

    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)
    

    My table looks like this:

    counters = Table('counters', metadata,
        Column('id', Integer, primary_key=True),
        Column('counter', Integer)
    )
    
    0 讨论(0)
  • 2020-12-04 22:26

    If you are using the SQL layer, then you can use arbitrary SQL expressions in the update statement:

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

    The ORM Query object also has an update method:

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

    The ORM version is smart enough to also update the count attribute on the object itself if it's in the session.

    0 讨论(0)
  • 2020-12-04 22:34

    If you have something like:

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

    You can increment fields like this:

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

    Or, if you have some mapped Models, you can write alternatively:

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

    Both versions will return the sql statement you have asked for. But if you don't include the column and just write m.counter += 1, then the new value would be calculated in Python (and race conditions are likely to happen). So always include a column as shown in the two examples above in such counter queries.

    0 讨论(0)
提交回复
热议问题