【问题标题】:Google App Engine return object with reference set带有引用集的 Google App Engine 返回对象
【发布时间】:2012-08-25 20:29:30
【问题描述】:

您好,我试图将 DataStore 背后的概念理解为 No-SQL 数据库,我试图获取的是一个对象列表,该列表已被另一个对象“引用”。像这样

class Person(db.Model):
    name = db.StringProperty(required=True)

class Contact(db.Model):
    name = db.StringProperty(required=True)
    email = db.StringProperty()
    trader = db.ReferenceProperty(Person)

这很好用,当我使用 person.put() 时它们会被保存,没有任何问题。但是当我尝试检索它并编码为 json 时,它从来没有将 contact 显示为列表,实际上它完全忽略了它。

    persons_query = Person.all()
    persons = persons_query.fetch(50)
    data = json.encode(persons)

我希望人们有一个联系人集合,但它对如何解决这个问题没有任何想法?

为了更清楚,目前我得到的是这样的:

[
 {
  name: "John Doe"
 }
]

我想成为

[
 {
  name: "John Doe"
  contacts: [{name:"Alex", email:'alex@gmail.com'}]
 }
]

编辑

谢谢你是对的,我需要获取联系人集合,只有一个问题是,当联系人被编码时,它递归地尝试对 Trader 对象进行编码,这是联系人等等。

所以我得到了一个明显的错误递归错误,对此的解决方案显然是在编码时从联系人中删除交易者对象。

【问题讨论】:

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


    【解决方案1】:

    在你的类中自定义 toJson 函数

    class Person(db.Model):
        name = db.StringProperty(required=True)
    
        def toJson(self):
            contact = self.contact_set #this is the default collection name for your class
            d = {"name":self.name,"contact":contact}
            return json.dumps(d)
    
    class Contact(db.Model):
        name = db.StringProperty(required=True)
        email = db.StringProperty()
        trader = db.ReferenceProperty(Person)
    

    那么你可以做ff:

    persons_query = Person.all()
    persons = persons_query.fetch(50)
    data = person.toJson()
    

    【讨论】:

      【解决方案2】:

      要获取所有联系人,您需要编写一个自定义 json 编码器,该编码器获取所有反向引用属性。

      ReferenceProperties 自动获得反向查询。来自文档“collection_name 是要提供给引用模型类的属性的名称。该属性的值是引用该实体的所有实体的查询。如果未设置 collection_name,则 modelname_set(具有引用的名称使用小写字母的模型并添加了_set)。”

      因此,您将添加一个方法来解决反向引用集查询。

      class Person(db.Model):
         name = db.StringProperty(required=True)
         def contacts(self):
             return self.contact_set.fetch(50)  # should be smarter than that
      

      然后在您的自定义 json 编码器中使用它。

      【讨论】:

        【解决方案3】:

        如果您想查找包含某个人的所有联系人,您需要为其发出查询。

        contacts = Contact.all().filter("trader =", person)
        

        【讨论】:

        • 如果我想在同一个对象中检索所有的人和他的联系人怎么办?
        • 您必须将联系人的副本非规范化并存储在 Person 对象中。如果您经常查询 Person,这可能是一个不错的方法,因为它使您不必查询联系人。但是,您还需要将数据与实际联系人保持同步。或者,如果您不介意进行额外的查询,您可以将两者合并到字典中并通过 json 编码器运行。
        猜你喜欢
        • 1970-01-01
        • 2011-05-16
        • 1970-01-01
        • 2017-11-17
        • 2017-01-10
        • 2011-01-22
        • 1970-01-01
        • 2011-06-17
        • 2010-12-24
        相关资源
        最近更新 更多