我使用db.Key实例的经典ListProperty
为gae中的多对多关系建模。
class Foo(db.Model):
name = db.StringProperty()
_bars = db.ListProperty(db.Key)
@property
def bars(self):
return Bar.gql("WHERE __key__ in :1", self._bars)
class Bar(db.Model):
name = db.StringProperty()
@property
def bands(self):
return Foo.gql("WHERE _bars = :1", self.key())
class QueryTest(unittest.TestCase):
def setUp(self):
db.delete(Foo.all().run())
db.delete(Bar.all().run())
def test_query_no_notification(self):
bar_1 = Bar(name="asdf")
bar_1.put()
bar_2 = Bar(name="qwer")
bar_2.put()
foo = Foo()
foo.put()
self.assertEqual(len([bar for bar in foo.bars]), 0)
def test_query_with_bars(self):
bar_1 = Bar(name="asdf")
bar_1.put()
bar_2 = Bar(name="qwe")
bar_2.put()
foo = Foo()
foo._bars.append(bar_1.key())
foo.put()
self.assertEqual(len([bar for bar in foo.bars]), 1)
在上面的代码中,第一个测试失败了。当_bars
ListProperty为空时,Bar.gql("WHERE __key__ in :1", self._bars)
将返回所有Bar对象(而不是无)。
但是,如果_bars
确实包含至少一个元素,则查询运行正常。
我很好奇这是否是GAE中的错误,或者我编写查询的方式是错误的......
由于
答案 0 :(得分:1)
这当然看起来很异常。你能运行AppStats,看看正在执行什么底层查询吗?
然而,你所做的并不是最有效的方式。当您运行SELECT * FROM Foo WHERE bar in :1
之类的查询时,SDK会将其分解为列表中每个项目的一个相等查询,并单独执行它们。但是,您尝试按键查找项目,并且数据存储区有一个内置方法来执行此操作。用以下内容替换当前查询:
return Bar.get(self._bars)