Many to many relation in GAE. Failing query
I've been modeling many to many relationships in gae using the classic ListProperty
of db.Key instances.
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()
开发者_JAVA百科 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)
In the code above, the first test is failing. When the _bars
ListProperty is empty, the Bar.gql("WHERE __key__ in :1", self._bars)
returns all Bar objects (instead of none).
However, if _bars
does contain at least one element, the query runs fine.
I'm curious if this is a bug in GAE, or the way I'm writing the query is wrong...
Thanks
This certainly look anomalous. Can you run AppStats, and see what underlying queries are being executed?
However, what you're doing is not the most efficient way. When you run a query like SELECT * FROM Foo WHERE bar in :1
, the SDK breaks this up into one equality query for each item in the list, and executes them separately. You're attempting to look up items by key, however, and the Datastore has a built in method to do this. Replace the current query with this:
return Bar.get(self._bars)
精彩评论