modelling in google-datastore: use lists or separate entities?

混江龙づ霸主 提交于 2019-12-11 12:29:23

问题


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 many events
  • each event has a list of numbers (its location) 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):

  1. one table, EntityName, with events as a ListProperty
    this would require nested lists in one table ... not sure if that's possible
  2. two tables, EntityName and Event
    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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!