gpt4 book ai didi

python - 如何使用 Elixir/SQLAlchemy 进行原子递增/递减

转载 作者:太空宇宙 更新时间:2023-11-03 11:10:50 25 4
gpt4 key购买 nike

我想增加(或减少)Elixir 实体中的分数字段:

class Posting(Entity):

score = Field(Integer, PassiveDefault(text('0')))

def upvote(self):
self.score = self.score + 1

但是,这对于并发调用 upvote 并不能可靠地工作。我能想到的最好的就是这个丑陋的困惑(基本上是用 SQLAlchemy 构建一个 SQL UPDATE 语句):

def upvote(self):
# sqlalchemy atomic increment; is there a cleaner way?
update = self.table.update().where(self.table.c.id==self.id)
update = update.values({Posting.score: Posting.score + 1})
update.execute()

您认为此解决方案有任何问题吗?有没有更清洁的方法来实现同样的目标?

我想避免在这里使用数据库锁。我正在使用 Elixir、SQLAlchemy、Postgres。

更新

这是从 vonPetrushev 的解决方案派生的变体:

def upvote(self):
Posting.query.filter_by(id=self.id).update(
{Posting.score: Posting.score + 1}
)

这比我的第一个解决方案要好一些,但仍然需要过滤当前实体。不幸的是,如果实体分布在多个表中,这将不起作用。

最佳答案

我会尝试,但我不确定这是否满足您的需求:

session.query(Posting).\
.filter(Posting.id==self.id)\
.update({'score':self.score+1})

你可能想在它之后立即执行 session.commit() ?

编辑:[关于问题的更新]

如果Posting是从类映射到多个表的Entity派生的,上面的解决方案仍然有效,但是Posting.id属性的含义发生了变化,即不再映射到某个表的列,而是映射到不同的组成。这里: http://docs.sqlalchemy.org/en/latest/orm/nonstandard_mappings.html#mapping-a-class-against-multiple-tables你可以看到如何定义它。我建议它会像:

    j = join(entity_table_1, entity_table_2)
mapper(Entity, j, properties={
'id': column_property(entity_table_1.c.id, entity_table_2.c.user_id)
<... some other properties ...>
})

关于python - 如何使用 Elixir/SQLAlchemy 进行原子递增/递减,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4167568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com