3

In App Engine for Python, is there anything like Objectify (Java Library) where I can easily embed a class within another and save it to the datastore?

This class would be modeled like the following example where a Venue contain a Location object. I want to persist this as one nested object, as well as be able to query by fields in the embedded object.

class Location():
  city = db.StringProperty()
  state = db.StringProperty()

class Venue(db.Model):
  name = db.StringProperty()
  location = Location()

Here is information on how it works in Objectify in App Engine for Java.
http://code.google.com/p/objectify-appengine/wiki/IntroductionToObjectify#@Embedded

Is this possible using Python?

Sam Edwards
  • 874
  • 8
  • 19

2 Answers2

3

Consider using Reference properties. I.e. store a Location object as its own entity and incorporate that location into the Venue object by reference.

class Location():
  city = db.StringProperty()
  state = db.StringProperty()

class Venue(db.Model):
  name = db.StringProperty()
  location = db.ReferenceProperty(Location)

Then, if you want to transact on a Location and Venue at the same time, use datastore transactions.

EDIT: To query fields in the 'contained' object, use datastore "back references". I.e. the fact that Venue contains a reference to Location means Location also contains references to Venues. See: http://code.google.com/appengine/docs/python/datastore/datamodeling.html#References

vsekhar
  • 5,090
  • 5
  • 22
  • 23
  • Thank you @vsekhar, I considered this, and it would achieve the functionality I'd desire, but it has downsides. 1. I have to maintain references between the two objects. 2. I would have two objects in the database where logically I only need one. 3. I couldn't query off of both "name" and "location.name" if desired because they are in different entities. 4. This would not allow me to easily serialize to a nested JSON structure that I'd want. 5. I know this concept of nesting properties is possible (logically at least) in the Java App Engine with Objectify, so I want that simplicity. – Sam Edwards Jul 20 '11 at 13:24
  • 2
    I hear you on the overhead of two vs. one object. If you want joint querying, you can lookup the key of the location and then query Venues by "venue.name=ABC" AND "venue.location=location_key". The whole concept behind web-scale databases is to do more work in code than in databases. Hence no enforced referential integrity, etc. It's just a design choice they made for the sake of scale that fits some applications and programming styles better than others. – vsekhar Jul 21 '11 at 01:17
2

Not currently, but the NDB library supports embedding models within one another either by serializing them as Protocol Buffers, or by nesting their properties (Objectify fashion).

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
  • Thank you! This project is attempting to do what I was looking for. "StructuredProperty: a property that lets you include one kind of model inside another, by value" It appears it is still in it's early stages and I am new to the Python runtime, so I will probably let it mature some before I end up using it, but I am glad to know someone is working on an elegant solution to what I would want. Here is more information on that project: https://docs.google.com/document/d/1dsx1hihmMXMJm8wIRu49tJR-KEng80o3wkg4Nlbqn-w/edit?hl=en&ndplr=1 – Sam Edwards Jul 20 '11 at 13:32