Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Limited traversal
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Andrey Popp  
View profile  
 More options Feb 16 2012, 4:39 pm
From: Andrey Popp <8may...@gmail.com>
Date: Fri, 17 Feb 2012 01:39:54 +0400
Local: Thurs, Feb 16 2012 4:39 pm
Subject: Re: Limited traversal

On Thu, Feb 16, 2012 at 12:09:36PM -0800, Mike Orr wrote:
> I'm weighing whether to use traversal in a limited way, and whether
> the benefits would outweigh the costs.

> I'm converting a Pylons application that has two database-related
> routes for read-only access:
> /incidents/{id}   => Incident ORM class
> /entries/{id} => Entry ORM class

> I can use URL dispatch in Pyramid, but then the views have to do the
> work of converting the ID into an int, and aborting 404 if it's
> invalid or the record doesn't exist, and check whether the user's
> permissions are compatible with the record's properties. (I don't have
> to check perms in this application because the database views hide
> non-public records, but I would in another application so I'm thinking
> ahead.) On the other hand, it's easy to generate a URL to any
> incident:  request.route_url("incident", id=incident_id)

> Using traversal, the resource tree would take care of fetching the
> database record and reporting if it doesn't exist, and it could also
> tie in with ACL permissions. I've verified that SQLAlchemy ORM
> instances don't have .__name__ or .__parent__ attributes so I could
> set these for location awareness.

As a side note, you could also use pyramid_traversalwrapper[1] "which wraps each
traversed object in a location-aware proxy", so you don't need to manage
__parent__ and __name__ attributes by yourself, I've found it pretty useful.

> So first, is this the right way to to it?  

I think it's fine.

> Second, how can I generate URLs to resources without loading the objects
> through this interface?  The home page queries the 30 most recent incidents
> and displays links to them.  request.resource_url() requires a resource
> object, but the home page or browse pages query the database directly and get
> plain ORM objects rather than location-aware ones.  I could make the URLs
> manually but that sucks. I could somehow get the "incident" resource and
> append the ID, or get the root resource and append "incident" and the ID, but
> that's not much better.

That's interesting question. I'm thinking of the following construct:

  1. Make your resource graph lazy, e.g. producing only proxies which only
  knows its location (pk in database in case of SQLAlchemy) and how to load
  itself (table and parent resources, which impose some query constraints or
  JOIN clauses).

  2. Reuse your resource graph in pyramid's traversal engine and in your home
  page view:

    def homepage():
      entries_ids = db.entries_ids_for_homepage()
      entries = [root["entries"][id] for id in entries_ids]

  So you get ``entries`` list of location-aware Entry objects which are loaded
  only if you access their fields, but not __name__ or __parent__ which allows
  you to generate URL for them w/o any overhead.

> Creating a traversal path ("/incident/123"), asking for the resource,
> and then generating the URL from it (which would be the same
> "/incident/123"), would be equally silly, and would also trigger a
> redundant query.

Why not memoize results of traversing? This kind of caching seems pretty
natural to me.

> And that raises another issue, the "incident" resource doesn't really
> exist. I.e., "/incident" should return an error, not connect to a
> regular view or default view. How do I do that? Or how do I make the
> default view be "not found"?

I'm sure it should exist -- it's a container of incidents! Any reasons you
don't want to expose it? If yes -- just adapt it to HTTPForbidden or something
like this.

[1]: http://pypi.python.org/pypi/pyramid_traversalwrapper/0.1


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.