Grok, sqlalchemy and traversalΒΆ

Tags: grokkerdam2008, plone

Martijn Faassen showed a grok + sqlalchemy application he's been working on. This got everyone into the spirit and more importantly into the problem domain. Something he used a lot was custom traversal to navigate the relational database model with URLs. With some quick pseudocode:

  from zope.location.location import located

  class Something(grok.Model):
      def traverse(self.name):
          item = session.query(...).first() # or .one()
          if item == None:
              return
          return located(item)

Storm is an alternative to sqlalchemy. Storm seems to be oriented more towards the needs of big complex projects. Sqlalchemy seems much more active open source community-wise. Storm is less "friendly" as you have to / can configure everything, just like zope3. Sqlalchemy seems more grok-like in outlook. At least, that's what I extracted from the discussion.

Grok discussion

An outcome of the discussion was that grok needs a to make it real easy to traverse to attributes. Unrelated to, but useful for, relational db integration. grok.traversable("something") was suggested. So this is in addition to the normal container traversal which effectively works with dictionary access (container["subitem_id"]). A shorthand that prevents you from having to write your own traverse() method in many common cases: so very grok-like.

A useful warning came up in the discussion. In zope, it is really easy to see everything as folders. In sql, you're making it all relational. Both are not 100% right object-oriented wise. Watch out for brainwashing based on your environment.

We went through the zope api docs for zope.app.container, writing down which sqlalchemy information we ought to use for treating the mapped sqlalchemy results as a container. This helped us to flush out some corner cases.

An essential point is to use sqlalchemy and its ORM mapper for the things that that is good at. As grok we won't do the sqlalchemy work, we'll just provide extra grok-specific functionality like traversal and folderish behaviour. Folderish behaviour means, as an example, in handling a "delete" correctly. Correctness is should be handled on the sqlalchemy level: if you configure your mapper right, the right thing will happen. That might sound dead-pan but it is, actually.

Grok also means: "not invented here: in a positive way". What other people figured out and did right is what we don't have to re-invent. So we won't invent it here.

Something that we'd need to figure out: how and where to define the classes, tables and mappers? Do we want it all easily in one class? Do we need to grok something?

Grok needs the fields for the add and edit forms. We didn't like defining an interface for the fields as that's partially double, partially potentially late-binding, etc. So something simple like:

 def form_fields(self):
     return grok.Fields(rdb.Schema(OurClass))

There was much more, but this ought to do for a summary. I didn't contribute much myself (especially since I have basically no grok experience!). I did learn a lot by listening, picking up useful concepts and ways of working. Nice sprint till now!

 
vanrees.org logo

Reinout van Rees

My name is Reinout van Rees and I program in Python, I live in the Netherlands, I cycle recumbent bikes and I have a model railway.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):