问题
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:
EntityName
has a few attributes, and manyevents
- each
event
has 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
, withevents
as a ListProperty
this would require nested lists in one table ... not sure if that's possible - two tables,
EntityName
andEvent
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