【问题标题】:How to get rid of _BaseValue如何摆脱 _BaseValue
【发布时间】:2013-01-14 02:49:58
【问题描述】:

我正在使用我自己的 ndb 属性子类,因此我可以向它们添加我自己的属性。 当我检索存储在 ndb 中的数据时,我经常(并非总是)检索 _BaseValue 包装器中的数据。如何避免返回 _BaseValues?
目前,当我想使用数据时,我必须先将其传递给函数以获取 b_val。

请求参数

INFO     2013-02-01 08:15:05,834 debug.py:24] discount_application          
INFO     2013-02-01 08:15:05,835 debug.py:24] url_name                      10
INFO     2013-02-01 08:15:05,835 debug.py:24] name                          10%
INFO     2013-02-01 08:15:05,835 debug.py:24] discount.amount               10
INFO     2013-02-01 08:15:05,835 debug.py:24] discount_type                 discount
INFO     2013-02-01 08:15:05,836 debug.py:24] free_text_discount            
INFO     2013-02-01 08:15:05,836 debug.py:24] discount.currency             euro

使用自定义函数从数据存储接收到的数据

created                       _BaseValue(datetime.datetime(2013, 1, 31, 10, 41, 6, 757020))
updated                       _BaseValue(datetime.datetime(2013, 2, 1, 8, 13, 34, 924218))
name                          _BaseValue('10%')
active                        _BaseValue(True)
name_lower                    _BaseValue('10%')
url_name                      _BaseValue('10_')
discount_type                 _BaseValue('free_text_discount')
discount                      _BaseValue(Discount(amount=0, currency=u'euro'))
free_text_discount            _BaseValue('Krijg nu 10% korting')
discount_application          _BaseValue(' ')

解析请求参数后的数据

created                       2013-01-31 10:41:06.757020
updated                       2013-02-01 08:13:34.924218
name                          u'10%'
active                        True
name_lower                    u'10%'
url_name                      u'10_'
discount_type                 u'discount'
discount                      Discount(amount=1000, currency=u'euro')
free_text_discount            u''
discount_application          u' '

据我所知,数据的存储方式是我想要的还是非随机的。 放样后收到相同实例后的数据如下图所示。放样后的数据也显示为 discount.discount.amount 和 discount.discount.currency,而不仅仅是 discount.amount 和 discount.currency

created                       _BaseValue(datetime.datetime(2013, 1, 16, 14, 29, 52, 457230))
updated                       _BaseValue(datetime.datetime(2013, 2, 1, 8, 14, 29, 329138))
name                          _BaseValue('20%')
active                        _BaseValue(True)
name_lower                    _BaseValue('20%')
url_name                      u'20_'
discount_type                 _BaseValue('discount')
discount                      _BaseValue(Discount(discount=Expando(amount=2000L, currency='percent')))
free_text_discount            _BaseValue(' ')
discount_application          _BaseValue('')

动作看起来像这样

# BaseModel has some default properties and inherits from CleanModel
class Action(BaseModel):
    _verbose_name = _("Action")
    max_create_gid = gid.ADMIN
    max_list_gid = gid.ADMIN
    max_delete_gid = gid.ADMIN

    # And some additional irrelevant properties
    # properties is a module containing custom properties,
    # which have some additional properties and functions
    discount = properties.StructuredProperty(Discount,
            html_input_type="small_structure",
            verbose_name=_("Discount"),
            help_message=_("Set a minimum discount of 10%% or € 1,00"),
            max_edit_gid=gid.ADMIN)

    def validate(self, original=None):
        return {}

折扣看起来像这样

# CleanModel has some irrelevant functions and inherits from ndb.Model
class Discount(common_models.CleanModel):
    amount = EuroMoney.amount.update(
            verbose_name=_("Discount"))
    currency = EuroMoney.currency.update(
            choice_dict=cp_dict(EuroMoney.currency._choice_dict,
                                            updates={CURRENCY_PERCENT: "%%"}),
            max_edit_gid=gid.ADMIN)

【问题讨论】:

  • 你实现了 _to_base_type 和 _from_base_type 方法吗?
  • 我试过了,但没有任何作用。我尝试了以下方法:def _from_base_value(self, value): return value
  • 你能提供你的代码吗?
  • 类型,不是值。检查 ndb/model.py 中的一些现有属性,它们通常执行诸如 return unicode(value) 之类的操作
  • 我到处使用 instance._values[propname] 来获取实例的值。现在我正在使用 getattr(instance, propname),这似乎效果更好。

标签: python google-app-engine google-cloud-datastore


【解决方案1】:

_values 永远不应该被使用。应该使用 getattr。
一个循环遍历模型属性的示例:

entity = Model(**kwargs)
for name in entity._properties:
    val = getattr(entity, name)

【讨论】:

    【解决方案2】:

    不知道这里是否是这种情况,但我遇到了同样的问题,因为我正在制作实体属性的本地副本,编辑它们,然后将它们放回实体中(下面的示例):

    # I had wanted to store a list of strings, so I made this class
    # (it was intended to store things like ["a", "b", "c"], etc.
    class lists(ndb.Model):
            thisList = ndb.StringProperty(repeated=True)
    
    def lets_go():
        with ndbclient.context():
            # Get the entity I want
            entity = ndb.Key(lists, "id").get()
            # Put it's existing data into a variable called 'local_list'
            local_list = entity.thisList
            # Append data to that variable
            local_list.append("d")
            # Assign the updated list back to the entity property
            entity.thisList = local_list 
    

    这会给你一个像这样的列表:["_BaseValue('a')", "_BaseValue('b')"...] 而不是 ["a", "b"...]是问题所在。

    如果我没记错的话,这实际上曾经在旧版本的 Google Cloud Datastore(大约 2018 年)中工作。但是,它现在给出了此处问题中提到的那种“_BaseValue”问题。这是我解决问题的方法——我直接编辑了 ndb 实体,没有制作列表的本地副本:

    def lets_go():
        with ndbclient.context():
            # Get the entity I want
            entity = ndb.Key(lists, "id").get()
            # And append data to it directly
            entity.localList.append("d")
            
    

    这会将一个实际的列表(如 ["a", "b"...])放入实体中。

    【讨论】:

      猜你喜欢
      • 2014-01-28
      • 2013-10-31
      • 2020-10-19
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多