重复的StructuredProperty中存储为_BaseValue的新实体
我有一个叫做 HUser
的模型,它是从谷歌的 User
类派生出来的。这个模型里面可以包含0到多个社交账号,这些账号可以是Facebook、Twitter或者LinkedIn的账号。我还建立了一个 Account
模型,并在我的 User
模型中定义了一个 StructuredProperty
,并设置了 repeated=True
,像这样:
class Account(ndb.Expando):
account_type = ndb.StringProperty(required=True, choices=['fb', 'tw', 'li'])
account_id = ndb.StringProperty()
access_token = ndb.StringProperty()
...
class HUser(User):
email = ndb.StringProperty(required=True, validator=validate_email)
created = ndb.DateTimeProperty(auto_now_add=True)
accounts = ndb.StructuredProperty(Account, repeated=True)
如果我只添加Facebook或LinkedIn账号,一切都正常。但是奇怪的是,每当我添加一个Twitter账号后,之后我再添加的所有账号都会被存储为 _BaseValue(Account())
,而不是直接存储为 Account()
。所以在我尝试获取这些账号的页面上,通常会出现这样的错误:
AttributeError: '_BaseValue' object has no attribute 'account_type'
我听说这些 _BaseValue
转换是谷歌的ndb源代码中的一个bug,但我该如何解决这个问题呢?目前我正在使用一个很糟糕的变通方法来绕过这些异常:
if type(account) == _BaseValue:
account = account.b_val
logging.warn("WARN: %s account %s was of type _BaseValue..." % (account.account_type, account.account_id))
谢谢你的帮助!
1 个回答
7
你是怎么访问你重复的属性的?ndb模型把属性存储为_BaseValue
,然后“无缝地”(不过这并不总是能做到)转换成你需要的类型(在ndb中叫做UserValue)。因此,你在模型外部存储属性时需要小心。想想这个:
myUser = HUser(...)
accounts = myUser.accounts
myUser.put()
accounts[0] # This is a _BaseValue(Account)
myUser.accounts[0] # This is an Account
这是一个关于ndb的公开错误,可以在ndb的问题追踪器上找到。