Plugins  {@name=plugins}
======================

SQLAlchemy has a variety of extensions and "mods" available which provide extra functionality to SA, either via explicit usage or by augmenting the core behavior.  Several of these extensions are designed to work together.

### SessionContext

**Author:**  Daniel Miller

This plugin is used to instantiate and manage Session objects.  It is the preferred way to provide thread-local session functionality to an application.  It provides several services:

* serves as a factory to create sessions of a particular configuration.  This factory may either call `create_session()` with a particular set of arguments, or instantiate a different implementation of `Session` if one is available.
* for the `Session` objects it creates, provides the ability to maintain a single `Session` per distinct application thread.  The `Session` returned by a `SessionContext` is called the *contextual session.*   Providing at least a thread-local context to sessions is important because the `Session` object is not threadsafe, and is intended to be used with localized sets of data, as opposed to a single session being used application wide.
* besides maintaining a single `Session` per thread, the contextual algorithm can be changed to support any kind of contextual scheme.
* provides a `MapperExtension` that can enhance a `Mapper`, such that it can automatically `save()` newly instantiated objects to the current contextual session.  It also allows `Query` objects to be created without an explicit `Session`.  While this is very convenient functionality, having it switched on without understanding it can be very confusing.  Note that this feature is optional when using `SessionContext`.

Using the SessionContext in its most basic form involves just instantiating a `SessionContext`:

    {python}
    import sqlalchemy
    from sqlalchemy.ext.sessioncontext import SessionContext
    
    ctx = SessionContext(sqlalchemy.create_session)
    
    class User(object):
        pass
    
    mapper(User, users_table)
    u = User()

    # the contextual session is referenced by the "current" property on SessionContext
    ctx.current.save(u)
    ctx.current.flush()

From this example, one might see that the `SessionContext`'s typical *scope* is at the module or application level.  Since the `Session` itself is better suited to be used in per-user-request or even per-function scope, the `SessionContext` provides an easy way to manage the scope of those `Session` objects.

The construction of each `Session` instance can be customized by providing a "creation function" which returns a new `Session`.  A common customization is a `Session` which needs to explicitly bind to a particular `Engine`:

    {python}
    import sqlalchemy
    from sqlalchemy.ext.sessioncontext import SessionContext
    
    # create an engine
    someengine = sqlalchemy.create_engine('sqlite:///')
    
    # a function to return a Session bound to our engine
    def make_session():
        return sqlalchemy.create_session(bind_to=someengine)
    
    # SessionContext
    ctx = SessionContext(make_session)
    
    # get the session bound to engine "someengine":
    session = ctx.current

The above pattern is more succinctly expressed using Python lambdas:

    {python}
    ctx = SessionContext(lambda:sqlalchemy.create_session(bind_to=someengine))

The default creation function is simply:

    {python}
    ctx = SessionContext(sqlalchemy.create_session)

The "scope" to which the session is associated, which by default is a thread-local scope, can be customized by providing a "scope callable" which returns a hashable key that represents the current scope:

    {python}
    import sqlalchemy
    from sqlalchemy.ext.sessioncontext import SessionContext
    
    # global declaration of "scope"
    scope = "scope1"
    
    # a function to return the current "session scope"
    def global_scope_func():
        return scope

    # create SessionContext with a custom "scopefunc"
    ctx = SessionContext(sqlalchemy.create_session, scopefunc=global_scope_func)
    
    # get the session corresponding to "scope1":
    session = ctx.current
    
    # switch the "scope"
    scope = "scope2"
    
    # get the session corresponding to "scope2":
    session = ctx.current

Examples of customized scope can include user-specific sessions or requests, or even sub-elements of an application, such as a graphical application which maintains a single `Session` per application window (this was the original motivation to create SessionContext).

#### Using SessionContextExt {@name=sessioncontextext}

This is a `MapperExtension` which allows a `Mapper` to be automatically associated with a `SessionContext`.  Newly constructed objects get `save()`d to the session automatically, and `Query` objects can be constructed without a session. The instance of `SessionContextExt` is provided by the `SessionContext` itself:

    {python}
    import sqlalchemy
    from sqlalchemy.ext.sessioncontext import SessionContext
    
    ctx = SessionContext(sqlalchemy.create_session)
    
    class User(object):
        pass
    
    mapper(User, users_table, extension=ctx.mapper_extension)

    # 'u' is automatically added to the current session of 'ctx'
    u = User()
    
    assert u in ctx.current
    
    # get the current session and flush
    ctx.current.flush()
    
The `MapperExtension` can be configured either per-mapper as above, or on an application-wide basis using:

    {python}
    import sqlalchemy
    from sqlalchemy.orm.mapper import global_extensions
    from sqlalchemy.ext.sessioncontext import SessionContext
    
    ctx = SessionContext(sqlalchemy.create_session)

    global_extensions.append(ctx.mapper_extension)

SessionContextExt allows `Query` objects to be created against the mapped class without specifying a `Session`.  Each `Query` will automatically make usage of the current contextual session:

    {python}
    # create a Query from a class
    query = Query(User)

    # specify entity name
    query = Query(User, entity_name='foo')

    # create a Query from a mapper
    query = Query(mapper)

    # then use it
    result = query.select()
    
When installed globally, all `Mapper` objects will contain a built-in association to the `SessionContext`.  This means that once a mapped instance is created, creating a new `Session` and calling `save()` with the instance as an argument will raise an error stating that the instance is already associated with a different session.  While you can always remove the object from its original session, `SessionContextExt` is probably convenient only for an application that does not need much explicit manipulation of sessions.

The user still has some control over which session gets used at instance construction time.  An instance can be redirected at construction time to a different `Session` by specifying the keyword parameter `_sa_session` to its constructor, which is decorated by the mapper:

    {python}
    session = create_session()  # create a new session distinct from the contextual session
    myuser = User(_sa_session=session)  # make a new User that is saved to this session

Similarly, the `entity_name` parameter, which specifies an alternate `Mapper` to be used when attaching this instance to the `Session`, can be specified via `_sa_entity_name`:

    {python}
    myuser = User(_sa_session=session, _sa_entity_name='altentity')

The decoration of mapped instances' `__init__()` method is similar to this example:    

    {python}
    oldinit = class_.__init__   # the previous init method
    def __init__(self, *args, **kwargs):
        session = kwargs.pop('_sa_session', None)
        entity_name = kwargs.pop('_sa_entity_name', None)
        if session is None:
            session = ext.get_session() # get Session from this Mapper's MapperExtension
            if session is EXT_PASS:
                session = None
        if session is not None:
            session.save(self, entity_name=entity_name)  # attach to the current session
        oldinit(self, *args, **kwagrs)   # call previous init method

### SelectResults

**Author:** Jonas Borgström

*NOTE:* As of verison 0.3.6 of SQLAlchemy, most behavior of `SelectResults` has been rolled into the base `Query` object.  Explicit usage of `SelectResults` is therefore no longer needed.

`SelectResults` gives transformative behavior to the results returned from the `select` and `select_by` methods of `Query`. 

    {python}
    from sqlalchemy.ext.selectresults import SelectResults

    query = session.query(MyClass)
    res = SelectResults(query)
    
    res = res.filter(table.c.column == "something") # adds a WHERE clause (or appends to the existing via "and")
    res = res.order_by([table.c.column]) # adds an ORDER BY clause

    for x in res[:10]:  # Fetch and print the top ten instances - adds OFFSET 0 LIMIT 10 or equivalent
      print x.column2

    # evaluate as a list, which executes the query
    x = list(res)

    # Count how many instances that have column2 > 42
    # and column == "something"
    print res.filter(table.c.column2 > 42).count()

    # select() is a synonym for filter()
    session.query(MyClass).select(mytable.c.column=="something").order_by([mytable.c.column])[2:7]

An important facet of SelectResults is that the actual SQL execution does not occur until the object is used in a list or iterator context.  This means you can call any number of transformative methods (including `filter`, `order_by`, list range expressions, etc) before any SQL is actually issued.

Configuration of SelectResults may be per-Query, per Mapper, or per application:

    {python}
    from sqlalchemy.ext.selectresults import SelectResults, SelectResultsExt
    
    # construct a SelectResults for an individual Query
    sel = SelectResults(session.query(MyClass))
    
    # construct a Mapper where the Query.select()/select_by() methods will return a SelectResults:
    mapper(MyClass, mytable, extension=SelectResultsExt())
    
    # globally configure all Mappers to return SelectResults, using the "selectresults" mod
    import sqlalchemy.mods.selectresults

SelectResults greatly enhances querying and is highly recommended.  For example, heres an example of constructing a query using a combination of joins and outerjoins:

    {python}
    mapper(User, users_table, properties={
        'orders':relation(mapper(Order, orders_table, properties={
            'items':relation(mapper(Item, items_table))
        }))
    })
    session = create_session()
    query = SelectResults(session.query(User))

    result = query.outerjoin_to('orders').outerjoin_to('items').select(or_(Order.c.order_id==None,Item.c.item_id==2))

For a full listing of methods, see the [generated documentation](rel:docstrings_sqlalchemy.ext.selectresults).
    
### assignmapper

**Author:** Mike Bayer

This extension is used to decorate a mapped class with direct knowledge about its own `Mapper`, a contextual `Session`, as well as functions provided by the `Query` and `Session` objects.  The methods will automatically make usage of a contextual session with which all newly constructed objects are associated.  `assign_mapper` operates as a `MapperExtension`, and requires the usage of a `SessionContext` as well as `SessionContextExt`, described in [plugins_sessioncontext](rel:plugins_sessioncontext).  It replaces the usage of the normal `mapper` function with its own version that adds a `SessionContext` specified as the first argument:

    {python}
    import sqlalchemy
    from sqlalchemy.ext.sessioncontext import SessionContext
    from sqlalchemy.ext.assignmapper import assign_mapper
    
    # session context
    ctx = SessionContext(sqlalchemy.create_session)
    
    # assign mapper to class MyClass using table 'sometable', getting
    # Sessions from 'ctx'.
    assign_mapper(ctx, MyClass, sometable, properties={...}, ...)

Above, all new instances of `MyClass` will be associated with the contextual session, `ctx.current`.  Additionally, `MyClass` and instances of `MyClass` now contain a large set of methods including `get`, `select`, `flush`, `delete`.  The full list is as follows:

    {python}
    # Query methods:
    ['get', 'select', 'select_by', 'selectone', 'get_by', 'join_to', 'join_via', 'count', 'count_by']

    # Session methods:
    ['flush', 'delete', 'expire', 'refresh', 'expunge', 'merge', 'save', 'update', 'save_or_update']

To continue the `MyClass` example:

    {python}
    # create a MyClass.  it will be automatically assigned to the contextual Session.
    mc = MyClass()
    
    # save MyClass - this will call flush() on the session, specifying 'mc' as the only
    # object to be affected
    mc.flush()
    
    # load an object, using Query methods attached to MyClass
    result = MyClass.get_by(id=5)
    
    # delete it
    result.delete()
    
    # commit all changes
    ctx.current.flush()

**Note:** : while the `flush()` method is also available on individual object instances, the instance-local flush() **does not flush dependent objects**.  For this reason this method may be removed in a future release and replaced with a more explicit version.

### associationproxy

**Author:** Mike Bayer and Jason Kirtland<br/>
**Version:** 0.3.1 or greater

`associationproxy` is used to create a simplified, read/write view of a relationship.  It can be used to cherry-pick fields from a collection of related objects or to greatly simplify access to associated objects in an association relationship.

#### Simplifying Relations

    {python}
    users_table = Table('users', metadata,
        Column('id', Integer, primary_key=True),
        Column('name', String(64)),
    )
    
    keywords_table = Table('keywords', metadata,
        Column('id', Integer, primary_key=True),
        Column('keyword', String(64))
    )

    userkeywords_table = Table('userkeywords', metadata,
        Column('user_id', Integer, ForeignKey("users.id"),
               primary_key=True),
        Column('keyword_id', Integer, ForeignKey("keywords.id"),
               primary_key=True)
    )

    class User(object):
        def __init__(self, name):
            self.name = name

    class Keyword(object):
        def __init__(self, keyword):
            self.keyword = keyword

    mapper(User, users, properties={
        'kw': relation(Keyword, secondary=userkeywords)
        })
    mapper(Keyword, keywords)

Above are three simple tables, modeling users, keywords and a many-to-many relationship between the two.  These ``Keyword`` objects are little more than a container for a name, and accessing them via the relation is awkward:

    {python}
    user = User('jek')
    user.kw.append(Keyword('cheese inspector'))
    print user.kw
    # [<__main__.Keyword object at 0xb791ea0c>]
    print user.kw[0].keyword
    # 'cheese inspector'
    print [keyword.keyword for keyword in u._keywords]
    # ['cheese inspector']

With ``association_proxy`` you have a "view" of the relation that contains just the `.keyword` of the related objects.  The proxy is a Python property, and unlike the mapper relation, is defined in your class:

    {python}
    from sqlalchemy.ext.associationproxy import association_proxy

    class User(object):
        def __init__(self, name):
            self.name = name

        # proxy the 'keyword' attribute from the 'kw' relation
        keywords = association_proxy('kw', 'keyword')

    # ...
    >>> user.kw
    [<__main__.Keyword object at 0xb791ea0c>]
    >>> user.keywords
    ['cheese inspector']
    >>> user.keywords.append('snack ninja')
    >>> user.keywords
    ['cheese inspector', 'snack ninja']
    >>> user.kw
    [<__main__.Keyword object at 0x9272a4c>, <__main__.Keyword object at 0xb7b396ec>]

The proxy is read/write.  New associated objects are created on demand when values are added to the proxy, and modifying or removing an entry through the proxy also affects the underlying collection.

- The association proxy property is backed by a mapper-defined relation, either a collection or scalar.
- You can access and modify both the proxy and the backing relation. Changes in one are immediate in the other.
- The proxy acts like the type of the underlying collection.  A list gets a list-like proxy, a dict a dict-like proxy, and so on.
- Multiple proxies for the same relation are fine.
- Proxies are lazy, and won't triger a load of the backing relation until they are accessed.
- The relation is inspected to determine the type of the related objects.
- To construct new instances, the type is called with the value being assigned, or key and value for dicts.
- A ``creator`` function can be used to create instances instead.

Above, the ``Keyword.__init__`` takes a single argument ``keyword``, which maps conveniently to the value being set through the proxy.  A ``creator`` function could have been used instead if more flexiblity was required.

Because the proxies are backed a regular relation collection, all of the usual hooks and patterns for using collections are still in effect.  The most convenient behavior is the automatic setting of "parent"-type relationships on assignment.  In the example above, nothing special had to be done to associate the Keyword to the User.  Simply adding it to the collection is sufficient.

#### Simplifying Association Object Relations

Association proxies are also useful for keeping [association objects](rel:datamapping_association) out the way during regular use.  For example, the  ``userkeywords`` table might have a bunch of auditing columns that need to get updated when changes are made- columns that are updated but seldom, if ever, accessed in your application.  A proxy can provide a very natural access pattern for the relation.

    {python}
    from sqlalchemy.ext.associationproxy import association_proxy

    # users_table and keywords_table tables as above, then:

    userkeywords_table = Table('userkeywords', metadata,
        Column('user_id', Integer, ForeignKey("users.id"), primary_key=True),
        Column('keyword_id', Integer, ForeignKey("keywords.id"), primary_key=True),
        # add some auditing columns
        Column('updated_at', DateTime, default=datetime.now),
        Column('updated_by', Integer, default=get_current_uid, onupdate=get_current_uid),
    )

    def _create_uk_by_keyword(keyword):
        """A creator function."""
        return UserKeyword(keyword=keyword)

    class User(object):
        def __init__(self, name):
            self.name = name
        keywords = association_proxy('user_keywords', 'keyword', creator=_create_uk_by_keyword)

    class Keyword(object):
        def __init__(self, keyword):
            self.keyword = keyword
        def __repr__(self):
            return 'Keyword(%s)' % repr(self.keyword)

    class UserKeyword(object):
        def __init__(self, user=None, keyword=None):
            self.user = user
            self.keyword = keyword

    mapper(User, users_table, properties={
        'user_keywords': relation(UserKeyword)
    })
    mapper(Keyword, keywords_table)
    mapper(UserKeyword, userkeywords_table, properties={
        'user': relation(User),
        'keyword': relation(Keyword),
    })


    user = User('log')
    kw1  = Keyword('new_from_blammo')

    # Adding a Keyword requires creating a UserKeyword association object
    user.user_keywords.append(UserKeyword(user, kw1))

    # And accessing Keywords requires traverrsing UserKeywords
    print user.user_keywords[0]
    # <__main__.UserKeyword object at 0xb79bbbec>

    print user.user_keywords[0].keyword
    # Keyword('new_from_blammo')

    # Lots of work.

    # It's much easier to go through the association proxy!
    for kw in (Keyword('its_big'), Keyword('its_heavy'), Keyword('its_wood')):
        user.keywords.append(kw)

    print user.keywords
    # [Keyword('new_from_blammo'), Keyword('its_big'), Keyword('its_heavy'), Keyword('its_wood')]


#### Building Complex Views

    {python}
    stocks = Table("stocks", meta,
       Column('symbol', String(10), primary_key=True),
       Column('description', String(100), nullable=False),
       Column('last_price', Numeric)
    )

    brokers = Table("brokers", meta,
       Column('id', Integer,primary_key=True),
       Column('name', String(100), nullable=False)
    )

    holdings = Table("holdings", meta,
      Column('broker_id', Integer, ForeignKey('brokers.id'), primary_key=True),
      Column('symbol', String(10), ForeignKey('stocks.symbol'), primary_key=True),
      Column('shares', Integer)
    )

Above are three tables, modeling stocks, their brokers and the number of shares of a stock held by each broker.  This situation is quite different from the association example above.  `shares` is a _property of the relation_, an important one that we need to use all the time.

For this example, it would be very convenient if `Broker` objects had a dictionary collection that mapped `Stock` instances to the shares held for each.  That's easy.

    {python}
    from sqlalchemy.ext.associationproxy import association_proxy
    from sqlalchemy.orm.collections import attribute_mapped_collection

    def _create_holding(stock, shares):
        """A creator function, constructs Holdings from Stock and share quantity."""
        return Holding(stock=stock, shares=shares)

    class Broker(object):
        def __init__(self, name):
            self.name = name

        holdings = association_proxy('by_stock', 'shares', creator=_create_holding)

    class Stock(object):
        def __init__(self, symbol, description=None):
            self.symbol = symbol
            self.description = description
            self.last_price = 0

    class Holding(object):
        def __init__(self, broker=None, stock=None, shares=0):
            self.broker = broker
            self.stock = stock
            self.shares = shares

    mapper(Stock, stocks_table)
    mapper(Broker, brokers_table, properties={
        'by_stock': relation(Holding,
            collection_class=attribute_mapped_collection('stock'))
    })
    mapper(Holding, holdings_table, properties={
        'stock': relation(Stock),
        'broker': relation(Broker)
    })

Above, we've set up the 'by_stock' relation collection to act as a dictionary, using the `.stock` property of each Holding as a key.

Populating and accessing that dictionary manually is slightly inconvenient because of the complexity of the Holdings association object:

    {python}
    stock = Stock('ZZK')
    broker = Broker('paj')

    broker.holdings[stock] = Holding(broker, stock, 10)
    print broker.holdings[stock].shares
    # 10

The `by_stock` proxy we've added to the `Broker` class hides the details of the `Holding` while also giving access to `.shares`:

    {python}
    for stock in (Stock('JEK'), Stock('STPZ')):
        broker.holdings[stock] = 123

    for stock, shares in broker.holdings.items():
        print stock, shares

    # lets take a peek at that holdings_table after committing changes to the db
    print list(holdings_table.select().execute())
    # [(1, 'ZZK', 10), (1, 'JEK', 123), (1, 'STEPZ', 123)]

Further examples can be found in the `examples/` directory in the SQLAlchemy distribution.

The `association_proxy` convenience function is not present in SQLAlchemy versions 0.3.1 through 0.3.7, instead instantiate the class directly:

    {python}
    from sqlalchemy.ext.associationproxy import AssociationProxy

    class Article(object):
       keywords = AssociationProxy('keyword_associations', 'keyword')


### orderinglist

**Author:** Jason Kirtland

`orderinglist` is a helper for mutable ordered relations.  It will intercept
list operations performed on a relation collection and automatically
synchronize changes in list position with an attribute on the related objects.
(See [advdatamapping_properties_entitycollections](rel:advdatamapping_properties_customcollections) for more information on the general pattern.)

Example: Two tables that store slides in a presentation.  Each slide
has a number of bullet points, displayed in order by the 'position'
column on the bullets table.  These bullets can be inserted and re-ordered
by your end users, and you need to update the 'position' column of all
affected rows when changes are made.

    {python}
    slides_table = Table('Slides', metadata,
                         Column('id', Integer, primary_key=True),
                         Column('name', String))

    bullets_table = Table('Bullets', metadata,
                          Column('id', Integer, primary_key=True),
                          Column('slide_id', Integer, ForeignKey('Slides.id')),
                          Column('position', Integer),
                          Column('text', String))

     class Slide(object):
         pass
     class Bullet(object):
         pass

     mapper(Slide, slides_table, properties={
           'bullets': relation(Bullet, order_by=[bullets_table.c.position])
     })
     mapper(Bullet, bullets_table)

The standard relation mapping will produce a list-like attribute on each Slide
containing all related Bullets, but coping with changes in ordering is totally
your responsibility.  If you insert a Bullet into that list, there is no
magic- it won't have a position attribute unless you assign it it one, and
you'll need to manually renumber all the subsequent Bullets in the list to
accommodate the insert.

An `orderinglist` can automate this and manage the 'position' attribute on all
related bullets for you.

    {python}        
    mapper(Slide, slides_table, properties={
           'bullets': relation(Bullet,
                               collection_class=ordering_list('position'),
                               order_by=[bullets_table.c.position])
    })
    mapper(Bullet, bullets_table)

    s = Slide()
    s.bullets.append(Bullet())
    s.bullets.append(Bullet())
    s.bullets[1].position
    >>> 1
    s.bullets.insert(1, Bullet())
    s.bullets[2].position
    >>> 2

Use the `ordering_list` function to set up the `collection_class` on relations
(as in the mapper example above).  This implementation depends on the list
starting in the proper order, so be SURE to put an order_by on your relation.

`ordering_list` takes the name of the related object's ordering attribute as
an argument.  By default, the zero-based integer index of the object's
position in the `ordering_list` is synchronized with the ordering attribute:
index 0 will get position 0, index 1 position 1, etc.  To start numbering at 1
or some other integer, provide `count_from=1`.

Ordering values are not limited to incrementing integers.  Almost any scheme
can implemented by supplying a custom `ordering_func` that maps a Python list
index to any value you require.  See the [module
documentation](rel:docstrings_sqlalchemy.ext.orderinglist) for more
information, and also check out the unit tests for examples of stepped
numbering, alphabetical and Fibonacci numbering.
    

### ActiveMapper

**Author:** Jonathan LaCour

Please note that ActiveMapper has been deprecated in favor of [Elixir](http://elixir.ematia.de/), a more comprehensive solution to declarative mapping, of which Jonathan is a co-author.

ActiveMapper is a so-called "declarative layer" which allows the construction of a class, a `Table`, and a `Mapper` all in one step:

    {python}
    class Person(ActiveMapper):
        class mapping:
            id          = column(Integer, primary_key=True)
            full_name   = column(String)
            first_name  = column(String)
            middle_name = column(String)
            last_name   = column(String)
            birth_date  = column(DateTime)
            ssn         = column(String)
            gender      = column(String)
            home_phone  = column(String)
            cell_phone  = column(String)
            work_phone  = column(String)
            prefs_id    = column(Integer, foreign_key=ForeignKey('preferences.id'))
            addresses   = one_to_many('Address', colname='person_id', backref='person')
            preferences = one_to_one('Preferences', colname='pref_id', backref='person')
    
        def __str__(self):
            s =  '%s\n' % self.full_name
            s += '  * birthdate: %s\n' % (self.birth_date or 'not provided')
            s += '  * fave color: %s\n' % (self.preferences.favorite_color or 'Unknown')
            s += '  * personality: %s\n' % (self.preferences.personality_type or 'Unknown')
        
            for address in self.addresses:
                s += '  * address: %s\n' % address.address_1
                s += '             %s, %s %s\n' % (address.city, address.state, address.postal_code)
        
            return s


    class Preferences(ActiveMapper):
        class mapping:
            __table__        = 'preferences'
            id               = column(Integer, primary_key=True)
            favorite_color   = column(String)
            personality_type = column(String)


    class Address(ActiveMapper):
        class mapping:
            id          = column(Integer, primary_key=True)
            type        = column(String)
            address_1   = column(String)
            city        = column(String)
            state       = column(String)
            postal_code = column(String)
            person_id   = column(Integer, foreign_key=ForeignKey('person.id'))
            
More discussion on ActiveMapper can be found at [Jonathan LaCour's Blog](http://cleverdevil.org/computing/35/declarative-mapping-with-sqlalchemy) as well as the [SQLAlchemy Wiki](http://www.sqlalchemy.org/trac/wiki/ActiveMapper).

### SqlSoup

**Author:** Jonathan Ellis

SqlSoup creates mapped classes on the fly from tables, which are automatically reflected from the database based on name.  It is essentially a nicer version of the "row data gateway" pattern.

    {python}
    >>> from sqlalchemy.ext.sqlsoup import SqlSoup
    >>> soup = SqlSoup('sqlite:///')

    >>> db.users.select(order_by=[db.users.c.name])
    [MappedUsers(name='Bhargan Basepair',email='basepair@example.edu',password='basepair',classname=None,admin=1),
     MappedUsers(name='Joe Student',email='student@example.edu',password='student',classname=None,admin=0)]

Full SqlSoup documentation is on the [SQLAlchemy Wiki](http://www.sqlalchemy.org/trac/wiki/SqlSoup).

