【问题标题】:fetching by foreign key elements in appengine datastore通过 appengine 数据存储区中的外键元素获取
【发布时间】:2012-04-14 09:11:05
【问题描述】:

我有三个数据库表:

class Book(bd.Model):
    title = db.StringProperty()
    pub_time = db.DateTimeProperty()
    subject = db.StringProperty()

class Author(db.Model):
    name = db.StringProperty()
    age = db.IntegerProperty()

class Match(db.Model):
    bk = ReferenceProperty(Book, collection_name='book')
    ath = ReferenceProperty(Author, collection_name='books_written')

问题:我想过滤作者ATH写的书,主题SUB

我的方法:

class BookSearch(webapp2.requestHandler):
    def post(self):
        b = Books.all().filter("subject =", 'SUB')
        a = Author.all().filter("name =", "ATH")
        ret = Match.all().filter("bk =", b). filter("ath =", a)
        self.response.out.write(ret.count())

但这不起作用,我得到一个错误:

BadValueError: Unsupported type for property  : <class 'google.appengine.ext.db.Query'>

【问题讨论】:

  • 在您的 Book 模型中添加 author = ReferenceProperty(Author) 不是更简单吗?这样以后你就可以做一个Book.all().filter("subject", 'SUB').filter("author", author_key).fetch() ?
  • 感谢您的建议,但是,对不起@alex 但是您为什么忘记一本书可以有多个作者?一个作者可以写多本书。
  • 对,抱歉,没看到。但是,只需使用ListProperty 然后:authors = ListProperty(Key) 很简单。我猜这个查询是一样的。
  • 顺便说一句,我强烈建议您使用新库 NDB,它可以让您执行类似 author = KeyProperty('Author', repeated=True) 的操作
  • 这是我想在我的项目中实现的最后一件事,已经完成和预先填充的事情太多了,我可能会在我的下一个项目中看看。

标签: python google-app-engine webapp2


【解决方案1】:

a 和 b 是查询而不是实体。您需要先获取实体,然后才能将其用作另一个查询中的过滤器:

class BookSearch(webapp2.requestHandler):
    def post(self):
        b = Books.all().filter("subject =", 'SUB').get()
        a = Author.all().filter("name =", "ATH").get()
        ret = Match.all().filter("bk =", b).filter("ath =", a)
        self.response.out.write(ret.count())

【讨论】:

  • 非常感谢,它救了我的命!!我正在考虑退出这个项目!
  • 这将获取关于主题 SUB 的第一本书并尝试将其与具有该名称的作者匹配,而不是显示该主题的所有书籍。为此,OP 需要摆脱 Match 类型并使作者成为书上的列表属性,然后对其进行过滤。
【解决方案2】:

您应该使用bk IN 而不是bk =,因为b 中的结果可以有多个值。

试试这个:

ret = Match.all().filter("bk IN", b). filter("ath IN", a)

文档在这里https://developers.google.com/appengine/docs/python/datastore/queryclass#Query_filter

【讨论】:

  • 还没有尝试过,但它可能会起作用,还有一个问题,说我确定只有一位名叫 ATH 的作者我如何使用get 而不是filter 写作。
  • 你不能。只有知道密钥才能get
  • 很抱歉,但上述解决方案不起作用,其中应该始终附加一个列表项。
  • 然后将您的值ba 转换为列表?
猜你喜欢
  • 2013-04-25
  • 1970-01-01
  • 2021-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 2021-05-20
  • 1970-01-01
相关资源
最近更新 更多