【问题标题】:NDB Repeated Property List with 'None' Values具有“无”值的 NDB 重复属性列表
【发布时间】:2014-05-12 20:11:48
【问题描述】:

我需要一个属性类型,它可以使用 Python 接口为 NDB 设置和获取 True、False 和 None 值。对于单个 Property 属性,这很容易做到。

但是,对于 repeated 属性属性 (repeated=True),似乎不可能将列表项设置为 None。无论我尝试过哪种方法,NDB 库都会引发异常。

一次尝试如下所示:

class LOGICAL(ndb.GenericProperty):

  def _set_value(self, entity, value):
    if isinstance(value, (list, tuple, set, frozenset)):
        for i, val in enumerate(value):
            if isinstance(val, str):
                if val.lower() in ('unknown', 'none'):
                    value[i] = None
    if isinstance(value, str):
        if value.lower() in ('unknown', 'none'):
            value = None
    ndb.Property._set_value(self, entity, value)

  def _validate(self, value):
    if isinstance(value, str):
        if value.lower() == 'true':
            return True
        if value.lower() == 'false':
            return False
        raise AssertionError('LOGICAL must be one of "true","false","unknown","none" or'
                             'True, False, None.')
    if value is not None:
        assert isinstance(value, bool)

此代码对于单个 LOGICAL 属性运行良好,但只要我想分配一个列表,例如 [True,'false',None],None 就会被拒绝。我从后台的“机器”和很长很长的堆栈跟踪中收到以下警告。

WARNING:root:initial generator _put_tasklet(context.py:270) raised AssertionError()
WARNING:root:suspended generator put(context.py:748) raised AssertionError()

如果我的任务是不可能完成的,或者采取哪种方法,请告诉我。

【问题讨论】:

  • 您需要查看完整的堆栈跟踪,您提供的位没有用。然后我们可以查看引发错误的较低级别的代码。我的直觉是你做不到,但需要查看导致错误的 ndb 或更低的特定代码。
  • 我想我解决了这个问题,但它并不漂亮。在我的 LOGICAL 类中,它是 ndb.Property 的子类,我重载了 Property._set_value 和 Property._apply_to_values,以简单地将 NDB _from_base_value 方法中出现的任何字符串“未知”替换为 None。

标签: python google-app-engine app-engine-ndb


【解决方案1】:

_validate 没有正确处理“未知”和“无”的情况:

        if value.lower() in ('unknown', 'none'):
            return None

然后,在函数的最后:

    return value

所以得到的函数是:

def _validate(self, value):
    if isinstance(value, str):
        if value.lower() == 'true':
            return True
        if value.lower() == 'false':
            return False
        if value.lower() in ('unknown', 'none'):    # Add these two lines
            return None
        raise AssertionError('LOGICAL must be one of "true","false","unknown","none" or'
                             'True, False, None.')
    if value is not None:
        assert isinstance(value, bool)
    return value

【讨论】:

  • 此解决方案无法解决问题。此外,在 _validate simple 中返回 None 告诉 NDB 不要转换该值。换句话说,当我输入 None 时,您将字符串 'unknown' 或 'none' 放入数据存储区。
  • 嗯...你是对的。也许这个答案会有所帮助:stackoverflow.com/a/19611871/584846
猜你喜欢
  • 1970-01-01
  • 2014-06-12
  • 1970-01-01
  • 2011-08-19
  • 2013-01-21
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多