【问题标题】:Update multiple columns using django F() object使用 django F() 对象更新多列
【发布时间】:2013-03-22 15:33:09
【问题描述】:

我有一个模型,它以每列一个整数统计数据为基础存储统计数据。我有一个处理上述统计数据更新的视图,如下所示:

class PlayerStats(models.Model):
    #In game stats - these represent the actual keys sent by the game
    NumberOfJumps = models.IntegerField(default=0)
    NumberOfDoubleJumps = models.IntegerField(default=0)
    NumberOfSilverPickups = models.IntegerField(default=0)
    NumberOfGoldPickups = models.IntegerField(default=0)
    NumberOfHealthPickups = models.IntegerField(default=0)

我基本上得到了我需要添加到存储在数据库中的当前统计数据的统计数据字典。

我真的不想从模型中提取所有数据然后再次更新它,因为如果可能的话,我想在数据库级别执行此操作。

一位同事建议我使用 django 的 F() 对象将其从视图代码中推出,主要是为了保持线程安全并避免任何 mysql 死锁(统计表可能会不断更新由不同的线程)

字典包含反映数据库中使用的键的键,所以目前我正在这样做:

def update_stats(new_stats):
    player_stats = PlayerStats(user=user, **new_stats)
    old_stats = player_stats.values()[0]
    updated_stats = {}
    for stat in new_stats:
        if old_stat[stat]:
            updated_stats[stat] = old_stats[stat] + new_stats[stat]
    PlayerStats.objects.filter(user=user).update(**updated_stats)

任何人都知道如何使用 F() 对象来实现这一点?

【问题讨论】:

    标签: python mysql django


    【解决方案1】:

    要使用models.F 进行更新,您需要构造类似

    qs.update(field_1=models.F('field_1')+field_1_delta,
              field_2=models.F('field_2')+field_2_delta, 
              ...)
    

    对于你的代码,它可能是

    new_stats = {
        'NumberOfHealthPickups': 99
        # ...
    }
    updated_stats = {}
    for stat in new_stats:
        updated_stats[stat] = models.F(stat) + new_stats[stat]
    PlayerStats.objects.filter(user=user).update(**updated_stats)
    

    【讨论】:

    • 这正是我想要的,因为我需要尽可能少地接触数据库。
    【解决方案2】:

    一种选择是逐个更新字段。

    此代码不会一次更新所有字段(因此可能会很慢,db-access-wise),但它是安全的(没有死锁,没有丢失更新)。

    user_stats = PlayerStats.objects.get(user=user)
    for stat, increment in new_stats.iteritems():
        user_stats.update(**{ stat: F(stat) + increment })
    

    【讨论】:

    • 在我的情况下,这种级别的数据库访问是不可接受的,但无论如何谢谢。
    猜你喜欢
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2021-03-05
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多