NDB查询祖先重复的结构化属性

时间:2012-09-16 09:03:33

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

我正在测试以下对象:

pk = ndb.Key(League, 'Premier League', 'Season', '2012/13')
o = Team(
    id = 'Chelsea',
    name ='Chelsea',
    leagues = [
       TeamInLeague(
           parent = pk,
           position = 1,
       ),],
)
o.put()

并且AssertionError: 0 != 1上的测试失败:

q = Team.query(ancestor=pk)
self.assertEqual(q.count(), 1)

我也尝试过以下测试:

q = Team.query(TeamInLeague(ancestor=pk))
self.assertEqual(q.count(), 1)

它在AttributeError: type object 'TeamInLeague' has no attribute 'ancestor'上失败了。

有没有办法按结构化属性的父查询?或者我做错了吗?我从the docs了解到我在创建时添加了父属性。

1 个答案:

答案 0 :(得分:1)

您不能使用祖先关系来做您想做的事。

实际上,在创建团队类时,您不提供父键。我想收集你想用Team对象作为父对象创建Team对象吗?

看起来像这样:

league_k = ndb.Key(League, 'Premier League', 'Season', '2012/13')
o = Team(
    id = 'Chelsea',
    name ='Chelsea',
    parent = league_k
)
o.put()

然而,像这样,您的数据模型中会存在缺陷。团队课将永远与联盟联系在一起。由于联盟显然包含一个赛季,下赛季你的球队将无法进入。

最好使用多对多关系,就像您已经在示例代码中开始的那样。这将涉及创建一个帮助类TeamInLeague,就像你已经做的那样。然后,您可以使用普通查询(而不是祖先查询)来确定哪个团队在哪个联盟中。但是,在这种情况下,我会考虑创建一个特殊的TeamInLeague类。这在概念上比使用重复属性更清晰,特别是重复的结构化属性。

此外,不需要在构造函数中指定所有对象属性。这不是jQuery。在许多情况下,在创建对象之后和put()之前创建对象关系更具可读性。

您的代码如下所示:

league_k = ndb.Key(League, 'Premier League', 'Season', '2012/13')
team = Team(id = 'Chelsea', name ='Chelsea')
o.put()
team_in_league = TeamInLeague(team=team.key(), league=league_k, pos=1)
team_in_league.put()