未为重复 StructuredProperty 中的 Expando 模型正确保存自定义属性 [英] Custom properties not saved correctly for Expando models in repeated StructuredProperty

查看:21
本文介绍了未为重复 StructuredProperty 中的 Expando 模型正确保存自定义属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Expando 模型作为另一个模型中重复的 StructuredProperty.即,我想将无限数量的 Accounts 添加到我的 User 模型中.由于 Accounts 可以根据它们的类型具有不同的属性(Accounts 是对社交网络帐户的引用,例如 Twitter 需要比 Facebook 的 OAuth 过程更多的信息),我有将我的 Account 模型设计为 Expando.我已在模型定义中添加了所有基本信息,但我计划为特定社交网络添加自定义属性(例如,Twitter 的特定 access_token_secret 属性).

I am trying to use an Expando model as a repeated StructuredProperty in another model. Namely, I would like to add an indefinite number of Accounts to my User model. As Accounts can have different properties depending on their types (Accounts are references to social network accounts, and for example Twitter requires more information than Facebook for its OAuth process), I have designed my Account model as an Expando. I've added all basic information in the model definition, but I plan to add custom properties for specific social networks (e.g., a specific access_token_secret property for Twitter).

1/你能确认下面的设计(Expando在重复的StructuredProperty)应该工作吗?

1/ Can you confirm the following design (Expando in repeated StructuredProperty) should work?

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)

2/现在我面临的问题是:当我将 Facebook 帐户添加到我的 HUser 实例时,一切正常;但是,当我将 Twitter 帐户附加到同一个实例并添加一个未在模型中声明的新属性时,问题就会出现,如下所示:

2/ Now the problem I am facing is: when I add a Facebook account to my HUser instance, everything works fine ; however the problem rises when I append a Twitter account to that same instance, and add a new property not declared in the model, like that:

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

此操作应该将访问令牌密钥保存在我的 User 的 Twitter Account 实例中,但实际上它保存在 Facebook 中em> Account 实例(在索引 0 处)!

This operation is supposed to save the access token secret in the Twitter Account instance of my User, but in fact it saves it in the Facebook Account instance (at index 0)!

我做错了什么?

谢谢.

推荐答案

这是 ndb 如何存储 StructuredProperty 的基本问题.Datastore目前没有办法存储这个,所以ndb基本上是爆你的属性.

This is a fundamental problem with how ndb stores the StructuredProperty. Datastore does not currently have a way to store this, so ndb basically explodes your properties.

例如,考虑实体:

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')))

这实际上会存储在一个看起来像这样的实体中:

This will actually get stored in an entity that looks like:

{
 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 不知道它应该为 None 填充 access_token_secret 字段脸书账号.当 ndb 重新填充您的实体时,它将为它看到的第一个帐户(即 facebook 帐户)填写 access_token_secret.

Because you are using an ndb.Expando, ndb doesn't know that it should populate the access_token_secret field with a None for the facebook account. When ndb repopulates your entities, it will fill in the access_token_secret for the first account it sees, which is the facebook account.

重组您的数据听起来是解决此问题的正确方法,但您可能希望让您的 HUser 成为该 HUserAccount 的祖先,以便您查询对于使用强一致性的用户帐户.

Restructuring your data sounds like the right way to go about this, but you may want to make your HUser an ancestor of the Account for that HUser so that you query for a user's accounts using strong consistency.

这篇关于未为重复 StructuredProperty 中的 Expando 模型正确保存自定义属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆