Sunday, April 15th, 2012

Checking out Pyramid

Today I went through the Single file tutorial in the Pyramid documentation. This tutorial was starting to sway me away from the framework, due to all I needed to do, just to create something as simple as a Tasks list application. I was seeing little benefit in using it over say Django. Rather than finishing the tutorial, I did skim through the rest of it, to see what it was all about though. I went on to the Wiki tutorial which uses SQLAlchemy. The initial project configuration was similar to other major frameworks, running a command-line program to start the project and select a few additional options. I was beginning to become more interested. The resulting project directory also contained some default templates, css, and images to work with. This is something which Django does lack in, and it expects you to create all your templates from scratch.

Unlike Django, in Pyramid, there isn't a single manage.py, but rather a large array of scripts in your binary folder. This makes it a little confusing at first, as I am used to using either django-admin or manage.py for project configuration.

A component I really like about Pyramid, is that it automatically comes with a nice debug_toolbar, it looks the exact same as django-debug-toolbar. The default template which comes with a Pyramid project looks modern, despite the copyright date on the bottom still displaying 2011, maybe I'm just a tad picky. The debug toolbar here comes with some extra sections I do not see in the Django version, namely Routes, Tweens, and Introspection. I especially like the inclusion of Introspection, as I am sure it will prove most useful with debugging of an application. I am most confused about Tween, as this is from Flash development, it does make me curious of it's exact purpose.

It feels like Pyramid is trying to be the next Django in some senses, where much of the work is taken care of, and there is separation in the project layout. For web development, I am still preferring the Django ORM over SQLAlchemy. Looking at a simple models.py in either framework shows which APIs are more straightforward:

from sqlalchemy import (
    Column,
    Integer,
    Text,
    )

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    )

from zope.sqlalchemy import ZopeTransactionExtension

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

class Page(Base):
    """ The SQLAlchemy declarative model class for a Page object. """
    __tablename__ = 'pages'
    id = Column(Integer, primary_key=True)
    name = Column(Text, unique=True)
    data = Column(Text)

    def __init__(self, name, data):
        self.name = name
        self.data = data

This is a very simple data model which basically describes a key/value store. This is SQLAlchemy/Pyramid's data model usage syntax. It appears to be overly complex for just describing a simple model. Here is the same model, but using Django's ORM:

from django.db import models

class Page(models.Model):
    name = models.TextField(unique=True)
    value = models.TextField()

In Django, that's all there is to it. It's easy to read and straightforward to develop. Although, I think the name field should really be a VARCHAR, not sure why the Pyramid tutorial uses a TEXT field. Django also provides customizable Fields, such as a SlugField, which works wonders during developing a web application. Anyways, enough bashing of the other framework/ORM, lets get back on topic with Pyramid.

I like that Pyramid has a setup.py module which can configure a dependency list, this makes deploying the application to a server or moving the application to a new server relatively simple. It reminds me of how Rails is setup.

Okay, so I went through the tutorial. Although Pyramid does not provide rapid development. It does seem to have it own perks. Since it is based on Paste, it simplifies deployment. The entire framework is right in your face, which means all components are very customizable without having to fight with the framework. I may use it one day, if I find a project which requires a good amount of customization which Django cannot provide. As I said in a previous blog post, it is really hard to leave the wonderful world of Django. I try to look at other frameworks, but Django seems to offer the best in rapid development, customizablity when I require it, and works behind the scenes when I don't.

As a web developer, I like to focus on my application and now how the underlying framework works. I want a nicely integrated API which is highly documented and very easy to understand and use. Over the course of all the frameworks I have tried in many different languages, Django seems to provide all of this, in one easy to download and install package. Other frameworks have so many dependencies, that I am sort of scared if one component blows up during an upgrade, how long it will take me to repair the damage. With Django, every component is developed and provided by the Django Project team and tested before being released. They are very independent in this regard, and I highly respect that independence. To that regard, I am going to put together a Django tutorial which mimics the Pyramid Wiki tutorial to display how much less code is required in Django, and how much more functionality can be given to the Wiki at the same time. Please check out this upcoming Tutorial and more in the Tutorials section of this website.

Comment #1: Posted 2 years ago by Tim Hoffman

A few things to note, pyramid isn't bound to a particular storage technology like django, so it can run easily (with out django-nonrel for instance) on appengine, zodb, mongo, storm, etc..... This gives you a lot of choices for certain application types.

The other big strength allows you to use different url mapping schemes. routes or traversal (object mapping).

Comment #2: Posted 2 years ago by Lucian

I'm totally willing deal with being more explicit when creating models just so I can use SQLAlchemy when querying. I've had to do so many stupid hacks to deal with Django's braindead ORM that can't even do outer joins.

Comment #3: Posted 2 years ago by caaakeeey

I think you've misrepresented the sqlachemy/pyramid example a great deal.

You have used an unnecessary construct, used a comment in only sqlachemy, not used sqlachemy's default constructor and used the imports to maximise verbosity.

Here's a fairer example:

import sqlalchemy as sa

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Page(Base):
__tablename__ = 'pages'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.Text, unique=True)
data = sa.Column(sa.Text)

Comment #4: Posted 2 years ago by mike bayer

As others have commented, this is a misrepresented comparison and I'm surprised you find it appropriate to blog a "comparison" of two ORMs, when one ORM you've obviously used for months/years, the other you've only perused one small code example on the website of *a totally different framework*.

SQLAlchemy has it's own documentation, at http://www.sqlalchemy.org/docs/. The usage paradigms and philosophies of this system are completely different from that of Django's and cannot be compared based on skimming one example.

If you'd like to blog a comparison of these two products, spending an equal amount of time using both would be a good start, but also note that SQLAlchemy's usage patterns are tailored towards full-throated use of the relational database, that means thinking in terms of sets and relational algebra. If you're just looking to store your objects and get them back without care to how the schema or SQL is represented, you'll likely be disappointed.

Comment #5: Posted 2 years ago by Joe Tennies

Look into Elixir (http://elixir.ematia.de). It's closer to the Django syntax.

import elixir as e

# similar to line in settings.py
e.metadata.bind = "sqlite:///page.sqlite"

class Page(e.Entity):
name = e.Field(e.UnicodeText, unique=True)
value = e.Field(e.UnicodeText)

Comment #6: Posted 2 years ago by Kevin Veroneau

Thank you for all your comments.

I do admit, I can be a tad "Pro Django" at times. I also admit that when I first started using Django, and didn't understand why it does it this way or that way, that I wanted to use my other framework again. Read back in the blog archives on this site, I think 2010 has the article where I was first learning Django, you will see how many negative reactions I has then. Once I understood what Django was all about, and why it does certain things the way it does, I feel in love with it.

I do jump a little too fast sometimes, I am sure I will come to love many other Python frameworks and packages in the near future. I really want to sit down with SQLAlchemy, as I can see lots of potential there. I am currently very comfortable with Django's ORM, as I have not needed to use the advanced SQL commands which SQLAlchemy provides. At the moment, Django's ORM does indeed do the job for me.

@Joe, thank you for that suggestion, I will have a look into that.

Since there is a Django-norel port, can someone perhaps make a Django-sqlalchemy port? You know with all the components working with Django and existing apps? I would love to see this.

Comment #7: Posted 2 years ago by Simon Davy

Like your ASP MVC comparision, it doesn't really look like you spent the time on pyramid to understand it. Rather than just listing the things it does different that django (and tagging them therefore as bad), you should try more to understand the reasoning behind *why* it does something different, as it's very often a considered decision.

Pyramid is very good for this, as it has some good design rational docs: http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/designdefense.html
Also, using paste indicated you were using pyramid 1.2. You should probably use pyramid 1.3 vs django 1.4 for a fairer comparison.

About Me

My Photo
Names Kevin, hugely into UNIX technologies, not just Linux. I've dabbled with the demons, played with the Sun, and now with the Penguins.




Kevin Veroneau Consulting Services
Do you require the services of a Django contractor? Do you need both a website and hosting services? Perhaps I can help.

If you like what you read, please consider donating to help with hosting costs, and to fund future books to review.

Python Powered | © 2012-2013 Kevin Veroneau