【问题标题】:Database update weirdness数据库更新异常
【发布时间】:2014-02-04 13:32:17
【问题描述】:

我正在用 Django 开发一个游戏,其中叛军的数量会在回合变化后更新。 Rebels 在 (MySQL) 数据库中以 0 到 100 的整数表示。

当我保存时,会发生这种情况:

print world.rebels
>>> 0

rebstab = 0
world.rebels += rebstab
world.save()

print world.rebels
>>> 0

但是,当我使用 F() 表达式时(据我所知,我应该避免出现竞争条件),会发生这种情况:

print world.rebels
>>> 0

rebstab = 0
world.rebels = F('rebels') + rebstab
world.save()

print world.rebels
>>> 100

发生了什么事?

【问题讨论】:

    标签: mysql django django-models


    【解决方案1】:

    我没有任何使用 F() 这样的对象的经验,所以这个答案可能没有用,但 having a look at the documentation it mentions

    为了访问以这种方式保存的新值,需要重新加载对象:

    reporter = Reporters.objects.get(pk=reporter.pk)
    

    因此您可能必须再次实际查询数据库才能看到更新后的值:

    print world.rebels
    >>> 0
    
    rebstab = 0
    world.rebels = F('rebels') + rebstab
    world.save()
    
    print World.objects.get(pk=world.pk)
    >>> 100
    

    编辑:还请看[查看您不需要将对象拉入内存并且可以在数据库级别执行所有操作的示例:

    World.objects.get(pk=...).update(rebels=F('rebels) + 1)
    

    【讨论】:

    • 除了值 已更新,因为我得到了不同的值。但是,我不知道为什么当我将更改设置为 0 时,我会获得最大数量的反叛者。我应该声明此更新在游戏的其余部分和管理员中可见,因此问题不限于此特殊功能。
    • 数据库已更新,但您在内存中的对象可能不是,因为 F() 引入了一个 可能不是的 SQL 调用(我又不是 100 %确定)更新到对象。另请注意我的更新
    • 我无法进行纯 SQL 更新,因为我有自定义保存方法。同样如上所述,问题不仅限于此功能,因此内存和数据库之间的对象冲突不会是问题。
    • 阅读文档,当您使用 F() 对象时,您正在创建 SQL 表达式:When Django encounters an instance of F(), it overrides the standard Python operators to create an encapsulated SQL expression; in this case, one which instructs the database to increment the database field represented by reporter.stories_filed.,因此请注意这可能会导致问题。
    • 这是怎么回事?我想做的只是一个简单的增量,world.rebels 是一个 IntegerField 而 rebstab 是一个整数。你是在告诉我 F() 对象中的 + 意味着不同的东西吗?
    【解决方案2】:

    我刚刚发现原因与 F() 对象本身无关,而是与自定义保存方法发生冲突。更深入的解释见Django F() objects and custom saves weirdness

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 1970-01-01
      • 2017-09-11
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      相关资源
      最近更新 更多