我有一个web2py定义的数据库表,用于计算特定用户发出请求的次数 - 因此它有整数列' user_id'和' n_req'。我不想为每个可能的用户填充零。相反,我想检查是否存在具有user_id的行,如果存在,则递增' n_req'一个,否则创建一个初始值为'n_req'为了避免竞争条件,我想使用单个update_or_insert调用来执行此操作,例如
db.count_table.update(db.count_table.user_id == uid, user_id = uid, n_req = n_req + 1)
我认为我不能这样做,因为它在递增时使用预先存在的n_req
值。那么如何告诉DAL n_req
的初始值。我可以这样做,例如,n_req = (n_req || 0) + 1
?
答案 0 :(得分:1)
在这种情况下,我认为您无法使用.update_or_insert
方法,因为n_rec
的值取决于是否找到记录。相反,你可以做这样的事情:
db.define_table('count_table',
Field('user_id', 'integer', unique=True),
Field('n_rec', 'integer', default=1))
def update_count(user_id):
return db(db.count_table.user_id == user_id).update(n_rec=db.count_table.n_rec + 1)
if not update_count(uid):
try:
db.count_table.insert(user_id=uid)
except db._adapter.driver.IntegrityError:
update_count(uid)
请注意n_rec
中.update
的值设置为db.count_table.n_rec + 1
,这将转换为SQL语句,该语句将使数据库增加现有值,而不是显式提供最终值重视自己。如果两个请求同时更新计数,这应避免竞争条件。
另请注意,unique
字段存在user_id
约束。这将防止竞争条件允许为同一用户创建两个记录。在这种情况下,try/except
将捕获生成的IntegrityError
,并且将对现有记录进行更新。