对于ndb.JsonProperty,值从一个实例泄漏到另一个实例

问题描述 投票:2回答:1

所以,我把我讨厌的问题缩小到了......

class TestModel(ndb.Model):
    json1 = ndb.JsonProperty(default={})

entity1 = TestModel()
entity1.json1['val1'] = 'added via entity1'

entity2 = TestModel()
entity2.json1['val2'] = 'added via entity2'
logging.warn('entity2.json1 = {}'.format(entity2.json1))

在日志中,我看到了这个:

... entity2.json1 = {'val2': 'added via entity2', 'val1': 'added via entity1'}

令人惊讶的是,非常危险,我看到第一个实例中设置的值entity1泄漏到第二个实例entity2

我期望TestModel的第二次实例化为我提供一个“干净”的实例是不合理的,特别是因为我有default={}用于JsonProperty?我应该做一些我不喜欢的事情。或者这可能是ndb的错误?

更新:到目前为止我最好的解决方法:总是做TestModel(json1={})。但我想我担心如果我们的某个开发人员忘记这样做,我们可能会将一个客户的数据泄漏到另一个客户的数据中。

更新:似乎已经向Google报告了错误。 35898756表明这种(错误的)行为可能发生在请求之间。它于3年前开放;还在等待修复。

google-app-engine app-engine-ndb google-app-engine-python
1个回答
1
投票

对于对这个问题感兴趣的人,我已经找到了一个让我晚上睡得更好的解决方法。它不符合上面的评论,所以我回答了我自己的问题(希望它没关系)......

这似乎是一个错误(见35898756),这是一个3岁,很可能不会很快修复。上面的解决方法包括做TestModel(json1={})总是或子类JsonProperty和使用我的自定义类总是,从来没有ndb的类(我将不得不重复所有其他类似的属性,如PickleProperty)。这些工作,但担心我,因为项目的每个开发人员都必须在代码库中始终做正确的事情。哈!

所以,这是一个解决方法,意味着“做正确的事情”本地化到我的模型(更少的代码需要担心)。

class TestModel(ndb.Model):
    json1 = ndb.JsonProperty(default={})

    def __init__(self, **kwargs):
        kwargs.setdefault('json1', {})     # <---- ADDED THIS!
        super(TestModel, self).__init__(**kwargs)

在我的模型的构造函数中,如果它不存在,请添加关键字arg以将属性设置为{}。这似乎可以防止值从一个实例泄漏到另一个实例。

© www.soinside.com 2019 - 2024. All rights reserved.