I'd like to increment (or decrement) a score field in an Elixir entity:
class Posting(Entity):
score = Field(Integer, PassiveDefault(text('0')))
def upvote(self):
self.score = self.score + 1
However, this doesn't work reliably with concurrent calls to upvote. The best I could come up with is this ugly mess (basically constructing an SQL UPDATE statement with SQLAlchemy):
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()
Do you see any problems with this solution? Are there cleaner ways to achieve the same?
I'd like to avoid using DB locks here. I'm using Elixir, SQLAlchemy, Postgres.
Update
Here is a variant which is derived from vonPetrushev's solution:
def upvote(self):
Posting.query.filter_by(id=self.id).update(
{Posting.score: Posting.score + 1}
)
This is somewhat nicer than my first solution but still requires to filter for the current entity. Unfortunately, this does not work if the Entity is spread over multiple tables.