since SA is not a framework, and also because its evident that
different people have different tolerances for verbosity, SA breaks
the golden python rule of "there should only be one obvious way to do
it". by allowing options for things to happen automatically, it
breaks "explicit is better than implicit", or at least gives you the
option to break that rule. we even still haven't fixed the hardcoded
pixel sizes on the website's CSS so SA is just a general outlaw in
many regards.
anyway, its also a product of SA taking a typical python route of
starting out as super-minimal and magical, and then the users
complaining that they couldnt understand/control what was going on.
so i think its best to view SQLAlchemy from the beginning in the most
explicit way possible, and then as those concepts are understood,
options for less explicit operation can be added in. the general
graph of explicit/implicit options is:
1. engines - plain / threadlocal
2. statement execution - via Connections (engine.connect()) / via
engine.execute / via metadata
3. metadata - unbound / bound
4. sessions - via create_session / via sessioncontext or threadlocal
5. mapped objects - using session.save()/update()/etc. or plugging
sessioncontext/threadlocal into mappers so that objects are
automatically attached
6. querying - via session.query(someclass) / via assignmapper
7. the whole package - ActiveMapper / explicit mappers
for #1, the "plain" engine is probably better. the "threadlocal"
engine allows some patterns that were popular in 0.1, namely that the
explicit Connection used is tracked against the current thread so
that multiple functions can share the same connection without passing
it around, and that you can call begin/commit directly on the engine
instance without keeping track of a transaction object. those
features i think are somewhat OK but are probably not worth the
confusion, even though they are pretty transparent and dont affect much.
for #2, we are talking about these three scenarios:
conn = engine.connect()
result = conn.execute(mytable.select())
result = engine.execute(mytable.select())
result = mytable.select().execute()
its hard to say which one is better here, it depends on the structure
of the application.
#3 is sort of combined with the #2 and determines if a statement can
execute itself. it also implies that you dont need to specify an
engine explicitly with create_session. I tend to go with unbound
metadata since it feels a little more flexible.
#4 - for quick things, i use create_session, for an application, you
probably want to use a sessioncontext. or just your own threadlocal
variable, which i find is even easier if you dont need the other
things sessioncontext can do.
#5 - i prefer the more explicit route for this, so that I can choose
when/what objects get placed in the session. a lot of people prefer
the more automatic route.
#6 - im not a fan of assignmapper, but there is an overwhelming
desire among the users to have this functionality since it gives much
more of an "active-record" feel to their objects. again, i like the
explicit approach.
#7 - this is the grand ballroom of implicit behavior, the full
"active record" approach that combines Tables, Mappers, Sessions into
one big ball :). I had always intended that SA would be flexible
enough to support an active record facade, but early on I stopped
working on it so that I could focus on the more explicit API which
was hard enough to get right. I then had the idea that "active
record" would not even be needed; by having just one approach which
is slightly more verbose, we'd be more pythonic (expicit/one way to
do it), and it only involved a few extra lines of code to have the
Table/Mapper/class be separate (sessions were still implicit at that
time). But then came the repeated cries of "SA is too complicated!
too hard !", which are still alive and well today...so i let them add
in ActiveMapper to which those who like that sort of thing are
adamant of its necessity.
the SA tutorial uses bound metadata but is otherwise explicit about
sessions and such. i think it gives the best mix of things that are
well suited to be "implicit" and other things that are clearer if
they are explicit.
On Sep 20, 2006, at 12:42 PM, Martin wrote:
>
> Hi all,
>
> I've been playing around with pylons + SQLAlchemy for quite some time
> now and things are starting to come together. However, there are some
> aspects that I am still wondering about... and seeing how many
> questions there are about Pylons + SQLAlchemy, it looks like others
> have questions, too. So, could we maybe set up a section in the
> docs/wiki about "SQLAlchemy best practices"?
>
> Things that I am still unsure about:
> 1) What is the recommended place to define the SQLAlchemy-engine?
> Currently, I have attached the enginge to the g-object... is this good
> or not?
>
> 2) Where best to initialize the SQLAlchemy session? In the
> models/__init__.py? Somewhere else? Or rather use the threadlocal-mod?
> (Mike Bayer does not recommend the latter, if I understand that other
> discussion thread correctly) Or rather sessioncontext-mod?
>
> 3) Better to define Tables with bound metadata or unbound metadata?
>
> I am aware that lots of different things actually work... that's why I
> am confused about which way is best. Anybody else wants to add some
> questions? Maybe we can collect questions and answers here, and later
> turn the results into a wiki page. Maybe Mike and Ben - knowing the
> internals - can help with some of the aspects?
>
> Cheers and thanks,
> Martin
>
>
> >
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---