【问题标题】:ndb query by KeyProperty通过 KeyProperty 进行 ndb 查询
【发布时间】:2014-06-06 23:37:58
【问题描述】:

我正在为 KeyProperty 查询而苦苦挣扎,但看不出有什么问题。

我的模特是

class MyList(ndb.Model):
  user = ndb.KeyProperty(indexed=True)
  status = ndb.BooleanProperty(default=True)
  items = ndb.StructuredProperty(MyRef, repeated=True, indexed=False) 

我使用适当的数据创建了一个 MyList 实例,并且可以正常运行以下内容

cls = MyList
lists = cls.query().fetch()

返回

[MyList(key=Key('MyList', 12), status=True, items=..., user=Key('User', 11))]

但是当我尝试按用户过滤时它失败了,即查找用户等于特定实体的列表;即使使用我刚刚用于插入的那个,或者来自上一个查询结果。

key = lists[0].user
lists = cls.query(cls.user=key).fetch()

返回

[]

但是使用status=True 作为过滤器可以正常工作,而且我看不到缺少什么?

我应该添加它发生在具有以下 v3_stub 的单元测试环境中

self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=0)                                   
self.testbed.init_datastore_v3_stub(                                                                               
  require_indexes=True,                                                                                      
  root_path="%s/../"%(os.path.dirname(__file__)),
  consistency_policy=self.policy
)

【问题讨论】:

  • 这是最终一致性的产物。它在 SDK 中进行仿真,在使用 SDK 进行测试时,您可以选择如何仿真或不进行仿真。事实证明,您知道您可以检索实体,因此它存在。关闭开发环境中的最终一致性作为另一项检查。但是你必须在你的设计中处理这个问题。
  • @TimHoffman:没错,如果我设置probability=1,它就可以正常工作,谢谢!然而,我不明白为什么不带参数的 query() 以及另一个过滤器(例如 status=True)有效。这是否意味着由于最终一致性,尚未创建索引?我认为最终一致性状态是“全有或全无”,而不是像这种情况下的“中间”,只有一些索引返回正确的数据。这是一个错误吗?
  • 我相信每个索引都会在它自己的时间更新。但是,您正在使用 SDK,它充其量是真实环境的近似值。您应该编写代码来处理 SDK 最终行为,因为这可能是最坏的情况。如果你的设计可以处理这个问题,那么你就可以处理生产。另一方面,如果您的设计仅在设置概率 = 1 时才有效,那么您处于滑坡上,并且在生产中会遇到问题。
  • @TimHoffman 我已经确保概率 = 0 适用于所有 get() 等,但索引问题有点 PITA。我添加了额外的缓存,所以现在可以正常工作了。我仍然认为不同的索引时间令人困惑(或者至少没有很好的记录)。再次感谢!
  • 索引已经/将要过时的事实是最终一致性的关键。正如您所发现的,get() 始终是一致的,除非 google 基础设施出现故障 - (我们已经看到)但是索引在更新之前总是有可变的时间量(通常很短)。这适用于删除和写入。

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


【解决方案1】:

user=Key('User', 11) 是另一个类的键:User。不是MyList

也许你的意思是:

user = ndb.KeyProperty(kind='User', indexed=True)

【讨论】:

  • 关于不同的类,我试图找到键是 User 实体的值,而不是 MyList 一个 - 我已经编辑了问题以明确这一点。我也试过 kind='User',同样的问题
【解决方案2】:

您的代码看起来不错,但是在使用 NDB 进行本地开发时,我注意到了一些数据完整性问题。我复制了你的模型和代码,一开始我也得到了空列表,但经过几次尝试,数据就在那里。

多试几次?

编辑:可能相关? google app engine ndb: put() and then query(), there is always one less item

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多