Using parent = or ancestor is probably faster because the locality of
datastore.
On Oct 13, 4:30 am, djidjadji <[EMAIL PROTECTED]> wrote:
> 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 [email protected]
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
-~----------~----~----~----~------~----~------~--~---