Hello, I'm looking for a way to store and retrieve a polymorphic one-to-many relation. The test case I used is for a drawing on a page to contain different shapes (lines,circles,...).
In my first attempt I used a ReferenceProperty in the Shape class to the Page class. (see code section 1) The objects (lines,circle) are stored correctly with all the attributes, but the Page object can't retrieve the shapes it contains probably because the shapes-Query looks something like "SELECT * FROM Shape WHERE onPage=:1", page and there is no Shape instance, only Line and Circle instances that have the correct onPage attribute. My second attempt is to use a ListProperty(db.Key) in the Page class, like suggested for the many-many relations. (see code section 2). Now the creation of the shapes with a classmethod, extra put for every shape created. The output I get is correct. The Page draws the shapes it contains. ------------------- Page: Number1 Line (0,0)-(10,5) in red Line (10,5)-(5,-10) in orange Page: Number2 Line (0,0)-(1,5) in black Circle (0,0)r3 in green ------------------- The question I have is, is this the most efficient method to store this from a datastore point of view? Is there a problem when the ListProperty(db.Key) has a lot of items? What number of items is no problem for a ListProperty? Will it have a big impact in retrieving a Page instance when it has a lot of 'shapes'/db.Key's in the list? djidjadji ------------------------------------------------- code section 1 BEGIN -------------------------------------------------------------------------------- import cgi import os from google.appengine.ext.webapp import template from google.appengine.ext import db from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app class Page(db.Model): name = db.StringProperty(required=True) def draw(self): drawing = '\n'.join(['\t'+s.draw() for s in self.shapes.fetch(1000)]) return 'Page: %s\n%s\n' % (self.name,drawing) class Shape(db.Model): onPage = db.ReferenceProperty(Page,collection_name="shapes",required=True) color = db.StringProperty(required=True,default='black') def draw(self): return '' class Line(Shape): startX = db.IntegerProperty(default=0) startY = db.IntegerProperty(default=0) endX = db.IntegerProperty(default=0) endY = db.IntegerProperty(default=0) def draw(self): return 'Line (%d,%d)-(%d,%d) in %s' % ( self.startX,self.startY,self.endX,self.endY,self.color) class Circle(Shape): centerX = db.IntegerProperty(default=0) centerY = db.IntegerProperty(default=0) radius = db.IntegerProperty(default=1) def draw(self): return 'Circle (%d,%d)r%d in %s' % ( self.centerX,self.centerY,self.radius,self.color) class MainPage(webapp.RequestHandler): def get(self): pages = '\n'.join([p.draw() for p in Page.all().fetch(1000)]) self.response.headers['Content-Type'] = 'text/plain' self.response.out.write(pages) class Create(webapp.RequestHandler): def get(self): page = Page(name='Number1') page.put() line = Line(onPage=page,endX=10,endY=5,color='red') line.put() line = Line(onPage=page,startX=10,startY=5,endX=5,endY=-10,color='orange') line.put() page = Page(name='Number2') page.put() line = Line(onPage=page,endX=1,endY=5) line.put() circle = Circle(onPage=page,startX=5,startY=0,radius=3,color='green') circle.put() self.redirect('/') application = webapp.WSGIApplication( [('/', MainPage), ('/create', Create), ], debug=False) def main(): run_wsgi_app(application) if __name__ == "__main__": main() ------------------------------------------------- code section 1 END ----------------------------------------------------------------------------------- ------------------------------------------------- code section 2 BEGIN ---- Changed methods ----------------------------------------------- class Page(db.Model): name = db.StringProperty(required=True) shapes = db.ListProperty(db.Key) def draw(self): drawing = '\n'.join(['\t'+s.draw() for s in db.get(self.shapes)]) return 'Page: %s\n%s\n' % (self.name,drawing) class Shape(db.Model): color = db.StringProperty(required=True,default='black') @classmethod def create(cls,onPage,**kwds): s = cls(**kwds) s.put() onPage.shapes.append(s.key()) # maybe better to put this in a transaction onPage.put() def draw(self): return '' class Create(webapp.RequestHandler): def get(self): page = Page(name='Number1') page.put() Line.create(onPage=page,endX=10,endY=5,color='red') Line.create(onPage=page,startX=10,startY=5,endX=5,endY=-10,color='orange') page = Page(name='Number2') page.put() Line.create(onPage=page,endX=1,endY=5) Circle.create(onPage=page,startX=5,startY=0,radius=3,color='green') self.redirect('/') ------------------------------------------------- code section 2 END ----------------------------------------------------------------------------------- --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to google-appengine@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en -~----------~----~----~----~------~----~------~--~---