skip to navigation
skip to content

pyramid_alchemy 0.0.1

Pyramid framework integration to extend SQLAlchemy ORM classes with separate, easily testable, code.

Good frameworks, like [Pyramid][] and [Angular][], help developers write
testable code. [SQLAlchemy][] is a great framework. However, the sheer
convenience of having model instances returned from a database query
encourages developers to write large ORM classes which can be hard to test.

One way to avoid this is to keep model classes [thin][] and write separate code
to instantiate and manipulate them. The downside of this approach is the loss in
convenience: the separated, easily testable code isn't provided by default as
an attribute of the model instances returned from a database query.

[pyramid_alchemy][] provides an `add_model_method` Pyramid
[configuration directive]() that extends [SQLAlchemy ORM][] classes in the same
way that `add_request_method` [extends the Pyramid Request][]. Using this
directive allows developers to write easily testable code that is conveniently
available as a model instance attribute. For example, if you [include][] this
in your Pyramid application:

from .model import Spam

def get_eggs(instance, source='hens', limit=9, offset=0):
"""Example ORM instance method, implemented as a standalone function."""

query = instance.query.filter_by(source=source)
return query.offset(offset).limit(limit)

def includeme(config):
config.add_model_method(Spam, get_eggs, 'get_eggs')

You can then use the `get_eggs` method from `Spam` instances:

spam = Session.query(Spam).get(1)
eggs = spam.get_eggs()

### Interfaces

Just as you can hang a Pyramid view off any context object implementing a
specific interface, you can extend any model instance implementing an interface.
For example, if your model looked something like this:

from sqlalchemy.ext.declarative import declarative_base
from zope.interfaces import implementer

from .interfaces import IFilling

Base = declarative_base()

class Ham(Base):
# ...

class Spam(Base):
# ...

Then you could extend all fillings -- current and future -- with:

config.add_model_method(IFilling, get_eggs, 'get_eggs')

### Limitations

Note that it's highly unlikely to be a good idea to use `add_model_method` to
add dynamic or hybrid methods that affect the underlying sql table or mapping.

[configuration directive]:
[SQLAlchemy ORM]:
[extends the Pyramid Request]:
File Type Py Version Uploaded on Size
pyramid_alchemy-0.0.1.tar.gz (md5) Source 2014-03-20 3KB