On 5/23/07, Qiangning Hong <[EMAIL PROTECTED]> wrote:
>
> On May 23, 9:58 pm, "Mike Orr" <[EMAIL PROTECTED]> wrote:
> > >http://docs.pythonweb.org/display/pylonscookbook/SQLAlchemy+for+peopl...
> > Use this one.  The way to set up the model is still evolving, but this
> > is the closest to the emerging standard.
>
> Could you please give some talk or resources about pros and cons about
> SQLAlchemry's default mapper, assign_mapper and Elixir?  Many newbies
> like me don't know which one is best suit for perticular situations.

Caveat: I've only used the default mapper.

The default mapper is the most widely used and tested, so the easiest
to get help on.  It's the least abmitious and magical, meaning it just
does its one little job.  The tradeoff is that you have to code more
verbosely.  The default mapper links an arbitrary class to a Table,
which links to a MetaData, which links to an Engine, which hands out
Connections to execute SQL.  The mapper can also link a class to
multiple related Tables.

Examples of queries with the default mapper:
    session.query(MyClass).select(MyClass.c.foo==2, limit=10)
    session.query(MyClass).select_by(foo=2)
    session.query(MyClass).get("Big Studly Record")
    session.query(MyClass).filter(MyClass.c.foo==2)[:10].list()

Example of data modification:
    bsr = session.query(MyClass).get("Big Studly Record")
    bsr.name = "Little Non-Studly Piece of Dirt"
    session.flush()
    # Behind the scenes, the object was linked to the session, which
    # tracks modifications and flushes them to the database in one step.

Sessions can't be shared between threads, so each thread has to create
its own sessions or use a global session_context which hands out a
thread-specfic session, creating one if it doesn't exist yet. When
using session_context, replace "session" above with
"session_context.current".  Pylons comes with a pre-initialized
session context for you, pylons.database.session_context.

The philosophy behind assign_mapper is what you really want to do is
query and modify your own classes, and you don't want to be bothered
with the session details.  So you link your class to a session_context
once at mapping time:
    assign_mapper(session_context, MyClass, my_table)

assign_mapper also adds two dozen methods to your class: query and
session methods.  So the above examples look like this:
    MyClass.select(MyClass.c.foo==2, limit=10)
    MyClass.select_by(foo=2)
    MyClass.filter ???    # Not sure if this exists.

    bsr = MyClass.get("Big Studly Record")
    bsr.date = datetime.date(2007, 10, 15)
    bsr.flush()

No session code, no .query() methods.  Behind the scenes it's really
doing the same thing as the first examples, of course.

Exilir provides a "declarative" way to define your tables and classes.
 This means you create the Table, class, and mapper in one step via a
single class definition.  The example on the Exilir home page is:

    class Person(Entity):
        has_field('name', Unicode(255))
        has_many('addresses', of_kind='Address')

    class Address(Entity):
        has_field('email', String(128))
        belongs_to('person', of_kind='Person')

I don't pretend to know exactly what this does, but I assume
person.addresses will be a list and address.person a string.  Thus
it's equivalent to:

    person_table= Table(...)
    address_table = Table(...)
    class Person(object):  pass
    class Address(object):  pass
    mapper(Address, address_table)
    mapper(Person, person_table, properties={
        "addresses":  relation(Person, backref="person"),
        })

Exilir exists because some people prefer designing their tables that
way.  In SQLObject this was the only way to define tables, and
apparently Ruby on Rails does it this way too.  Personally, I feel the
opposite: the separation of the SQL layer (Table) from the ORM (mapped
classes) is what drew me to SQLAlchemy in the first place.

Exilir home page:  http://elixir.ematia.de/

If we're mentioning all these mappers, we should also mention SqlSoup,
which is another extension included in SQLAlchemy.  it lets you access
existing tables without having to define anything.

    db = SqlSoup(DSN_or_metadata)   # Hides a metadata and engine.
    db.my_table.select(...)
    db.my_table.insert(foo="Bar", baz="Blech")
    db.my_table.update(criterion==2, baz="Blech")

I'm not sure if it actually creates a mapper for each table; the
return value of .select() is a list of Mapped_TheTable objects,
whatever they are.

-- 
Mike Orr <[EMAIL PROTECTED]>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to