问题
I'm stuck trying to implement a data model for an app to be deployed on AppEngine.
Here's an example of the model:
EntityName
id: 1
author: 'me'
description: 'whatever'
datetime: 2011 etc.
events: [
{location: [1,2], phase: ['A', 'B']},
{location: [3,4], phase: ['C', 'B']},
... more events ...
]
Explanation:
EntityNamehas a few attributes, and manyevents- each
eventhas a list of numbers (itslocation) and a list of strings (phase)
How can this model be implemented in AppEngine? The data only needs to be searchable by id, author, datetime, and description.
What I've tried to figure out how to do (still going through the docs) (sticking point in italics):
- one table,
EntityName, witheventsas a ListProperty
this would require nested lists in one table ... not sure if that's possible - two tables,
EntityNameandEvent
needs a join, which I understand isn't directly possible
回答1:
These aren't tables, exactly, but I think this should work for you
class EntityName(db.Model):
author = db.StringProperty(...)
class Event(db.Model):
entity_name = db.ReferenceProperty(EntityName, collection_name='events')
location = db.StringListProperty()
phase = db.StringListProperty()
Then...
e = EntityName(author='me', ...)
e.put()
event = Event(entity_name=e, location=...)
event.put()
for ev in e.events:
print ev.location
print ev.phase
See the documentation for details. You don't need to "do a join" because this isn't a SQL database. For your convenience, collection_name will create an iterator on the referenced side of a one-to-many relationship.
回答2:
Here's an alternative that only uses one model (i.e., Nick's idea):
import webapp2
from google.appengine.ext import db
class EntityName(db.Model):
author = db.StringProperty()
# ...
event_locations = db.StringListProperty(indexed=False)
event_phases = db.StringListProperty(indexed=False)
class MainHandler(webapp2.RequestHandler):
def get(self):
e = EntityName(author='me',
event_locations=['1,2', '3,4'], event_phases=['A,B', 'C,D'] )
e.put()
q = EntityName.all().filter('author =', 'me')
text = ''
for en in q:
for locations, phases in zip(en.event_locations, en.event_phases):
text += "location=%s, phase=%s<br>" % (locations, phases)
self.response.out.write(text)
app = webapp2.WSGIApplication([('/', MainHandler)], debug=True)
Sample output:
location=1,2, phase=A,B
location=3,4, phase=C,D
Since order is generally preserved in List and StringList properties, your locations and phases for an event can be matched up -- i.e., they have the same index in the two lists.
With one model you have to do a little more work splitting out each entry in the list, but you save on datastore reads and writes, since you only have one entity.
来源:https://stackoverflow.com/questions/8929943/modelling-in-google-datastore-use-lists-or-separate-entities