在GAE数据库上进行反向引用查询

标签:Google App Engine, Python

今天在GAE的论坛看到一篇题为《Using referenced class properties in GQL Query WHERE clause》的帖,发现是有人弄错了ReferenceProperty的查询方式。

他的查询如下:
class Thread(db.Model):
   user = dbReferenceProperty(User)

class User(db.Model):
  email = db.EmailProperty()

Thread.gql("WHERE user.email = :1", email)
于是提示.email有错。

实际上,GAE的数据库需要一个索引才能查询。当我们对Thread模型进行查询时,它只在user这个属性上有索引,而user.email这个属性是不存在的,自然没有索引。
为了达到他想要的查询效果,必须查询User模型的email字段,拿到user实体后,再获取其反向引用。
也就是:
user = User.gql('WHERE email = :1', email).get()
thread = user.thread_set[0]
那个thread_set并不存在于User模型的定义中,但是当Thread类引用User类时,User模型就会自动增加一个名为thread_set的反向引用属性。
当然,这个名字可以自己设定,详细信息可以参考Entities and Models的References这段。
此外,你还可以参考《在GAE的数据库中实现多对多的关系》

最后给个完整的例子:
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class Put(webapp.RequestHandler):
  def get(self):
    user = User(email='keakon@keakon.cn')
    user.put()
    Thread(user=user).put()

class Get(webapp.RequestHandler):
  def get(self):
    user = User.gql('WHERE email = :1', 'keakon@keakon.cn').get()
    thread = user.thread_set[0]
    if thread:
      self.response.out.write(thread.user.email)

application = webapp.WSGIApplication([
                                      ('/put', Put),
                                      ('/get', Get)])

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()

1条评论 你不来一发么↓ 顺序排列 倒序排列

    向下滚动可载入更多评论,或者点这里禁止自动加载

    想说点什么呢?