SQLAlchemy usage in TurboGears

17 views
Skip to first unread message

Christoph Zwerschke

unread,
Sep 29, 2008, 5:22:35 PM9/29/08
to sqlal...@googlegroups.com
Hi Michael,

we're just discussing some issues with SQLAlchemy over at the TurboGears
mailing list which appeared because the new SQLAlchemy usage as promoted
in the 0.5 docs differs from the classical usage. We are unsure how to
solve these issues, so I thought it will be best to get some input and
suggestions from you.

In the TurboGears project, our standard application templates for
SQLAlchemy create models in the classical (non-declarative) way.

To make this a bit more convenient, TurboGears creates a scoped session
and maps the model classes with this session's mapper (i.e. with a
contextual, session-aware mapper that is made available to the
TurboGears application). This worked very well for us, but now with SA
0.5, the declarative usage becomes more popular, which uses a normal
(not contextual) mapper. The existence of contextual mappers is not even
mentioned any more in the SA 0.5 docs. Is this an omission or is my
impression right that you want to phase out this kind of usage?

Another point is that our default scoped_session(create_session) in
TurboGears creates sessions with autoflush=False and autocommit=True,
while defaults sessionmaker() sessions in SQLAlchemy now have the
opposite, autoflush=True and autocommit=False. So maybe our usage is
outdated in that regard, too?

What kind of usage do you suggest to provide as default in our
TurboGears app templates that will be as convenient for the average user
and as future-safe as possible?

-- Christoph

Michael Bayer

unread,
Sep 29, 2008, 6:08:25 PM9/29/08
to sqlal...@googlegroups.com

your current approach of using classical mappings with Session.mapper
is entirely supported. sessionmaker() and create_session retain the
same defaults as they did in 0.4 as well. The name of the
"transactional" flag has been renamed to "autocommit" with a flip in
its boolean status, but the "transactional" flag works throughout 0.5
with a deprecation warning.

So as far as "future safe", you're entirely fine.

Now as far as where its going, we are pushing the declarative syntax,
particularly for people in the "up and running" mindset, because it
suits a large number of applications and removes the common SQLA
criticism that our configuration is "too verbose". Declarative is in
fact just a very thin configurational layer on top of the standard
mapper() and Table constructs, so it works with all current mapper
configurations, including Session.mapper - just pass Session.mapper as
the "mapper" keyword argument in declarative_base(). The declarative
system is sparse and open ended, works in conjunction with explicit
Table objects as well as explict mapper() setups, can be customized at
the metaclass or base class level, and can be used *without* a
metaclass too which is how Grok is doing it. So if your users seem
to prefer that syntax, you probably want to push TG towards that
approach.

As far as why Session.mapper itself isn't talked about much, the
existence of that feature is to me, a historical one dating back to
the 0.1 series. It provides three pieces of functionality - a
default __init__() method which populates an instance from keyword
arguments, a "query" attribute which is shorthand for
Session.query(cls), and it automatically "saves" the instance to the
Session upon init (now called add()). The most controversial
function is the auto-save. Back when the feature was more popular, we
regularly would get users that were confused when they tried to work
with explicit sessions and add objects to them, since they were
magically saved on construction. When the autoflush option was
introduced, we had users who couldn't use it because it would flush()
the object before __init__ had completed, for __init__ methods that
used the Query to locate dependent data. It saves before __init__
proceeds, and we couldn't even change that because it would break
other people's code.

Because SQLA really doesn't want to be in the "framework" business,
we've pulled way back on Session.mapper. The __init__() method it
provides is trivial to implement in a base class, and is also provided
when using the declarative extension. The "query" attribute is also
trivial to implement, but we've added a helper onto Session called
query_property() which provides this. If an application wishes to
have a certain set of behaviors for all of its mapped classes, we
really want developers to create their own base classes which provide
whatever functionality they want. This idea has been prevalent since
we introduced 0.4.

So without reading the thread, I think declarative would probably be
good, you can use it with Session.mapper if you want, though I view
Session.mapper as somewhat legacy.

Christoph Zwerschke

unread,
Oct 2, 2008, 6:11:51 AM10/2/08
to sqlal...@googlegroups.com
Michael Bayer schrieb:

> your current approach of using classical mappings with Session.mapper
> is entirely supported. ...

> So without reading the thread, I think declarative would probably be
> good, you can use it with Session.mapper if you want, though I view
> Session.mapper as somewhat legacy.

Thank you for these clarifications. So we will probably keep the old
contextual session and mapper, but not propgate that usage any longer,
and rewrite the templates for the declarative usage.

-- Christoph

Reply all
Reply to author
Forward
0 new messages