如何使用Elixir/SQLAlchemy进行原子增量/减量

2024-10-01 13:27:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我想增加(或减少)长生不老药实体中的分数字段:

class Posting(Entity):

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

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

但是,这在并发的upvote调用中不能可靠地工作。我能想到的最好的办法就是这样一团乱麻(基本上是用SQLAlchemy构造一个SQL UPDATE语句):

^{pr2}$

你觉得这个解决方案有什么问题吗?有没有更干净的方法来达到同样的效果?在

我想避免在这里使用数据库锁。我在用长生不老药,炼金术,博士后。在

更新

以下是从冯佩特鲁舍夫的解决方案中衍生出来的一个变体:

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

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


Tags: textself实体idfielddef数字integer
1条回答
网友
1楼 · 发布于 2024-10-01 13:27:37

我会试试,但我不确定这是否符合您的需要:

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

你可能想这么做会话.提交()就在那之后?在

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

如果过帐是从类映射到多个表的实体派生的,上面的解决方案仍然有效,但是过帐.id属性已更改,即不再映射到某个表的列,而是映射到另一个组合。在这里: http://docs.sqlalchemy.org/en/latest/orm/nonstandard_mappings.html#mapping-a-class-against-multiple-tables 你可以看到如何定义它。我建议应该是:

^{pr2}$

相关问题 更多 >