我正在尝试将Expando
模型用作另一个模型中的重复StructuredProperty
。也就是说,我想向我的Accounts
模型添加无限数量的User
。由于Accounts
可以根据其类型具有不同的属性(Accounts
是对社交网络帐户的引用,例如Twitter在OAuth流程中需要比Facebook更多的信息),我设计了{{1} }模型为Account
。我已在模型定义中添加了所有基本信息,但我计划为特定社交网络添加自定义属性(例如,Twitter的特定Expando
属性)。
1 /您能否确认以下设计( 2 /现在我遇到的问题是:当我向我的 此操作应该将访问令牌密钥保存在 我做错了什么? 感谢。access_token_secret
Expando
StructuredProperty
实例添加Facebook帐户时,一切正常;但是,当我将Twitter帐户附加到同一个实例时,问题就会增加,并添加一个未在模型中声明的新属性,如:class Account(ndb.Expando):
account_type = ndb.StringProperty(required=True, choices=['fb', 'tw', 'li'])
account_id = ndb.StringProperty()
state = 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)
HUser
的Twitter for account in huser.accounts:
if account.state == "state_we_re_looking_for" and account.account_type == 'tw':
# we found the appropriate Twitter account reference
account.access_token_secret = "..." # store the access token secret fetched from Twitter API
huser.put() # save to the Datastore
break
实例中,但事实上它将其保存在 Facebook {{1}中实例(在索引0处)!
答案 0 :(得分:1)
根据我的理解,App Engine NDB似乎不支持包含Expando
个实体的Expando
个实体。
我最初没有意识到的一件事是我的HUser
模型继承自Google的User
类,这正是Expando
模型!
所以我甚至不知道它,我试图将StructuredProperty
Expando
个Expando
个对象放在另一个Account
内,似乎不支持(I然而,没有找到任何关于这个限制的明确写法。
解决方案是以不同的方式设计数据模型。我将Expando
个对象放在一个单独的实体类中(这次,它们是真正的KeyProperty
个对象!),我添加了HUser
来引用{{1}}实体。这涉及更多的读/写操作,但代码实际上更容易阅读...
我会将自己的问题标记为已回答,除非有人对此处发现的限制有另一个有趣的意见。
答案 1 :(得分:1)
这是ndb如何存储StructuredProperty
的基本问题。数据存储目前没有办法存储它,所以ndb基本上会破坏你的属性。
例如,考虑实体:
HUser(email='test@example.com'.
accounts=(Account(type='fb',
account_id='1',
state='1',
access_token='1'),
Account(type='tw',
account_id='2',
state='2',
access_token='2',
access_token_secret='2')))
这实际上会存储在一个看起来像这样的实体中:
{
email : 'test@example.com',
accounts.type : ['fb', 'tw'],
accounts.account_id : ['1', '2'],
accounts.state : ['1', '2'],
accounts.access_token : ['1', '2'],
accounts.access_token_secret : ['2']
}
由于您使用的是ndb.Expando
,因此ndb不知道它应该使用access_token_secret
填充None
字段用于Facebook帐户。当ndb重新填充您的实体时,它会为其看到的第一个帐户填写access_token_secret
,即facebook帐户。
重新构建数据听起来像是正确的方法,但您可能希望让您的HUser成为Account
的{{1}}的祖先,以便您使用{查询用户的帐户{3}}