On Apr 6, 2006, at 11:37 PM, Daniel Miller (said that he preferred):
t = Table('mytable', columns...)
something.get_connection().execute(t.select())
see i dont like that syntax at all. if im writing a program that
just connects to a single database, i dont want to have to worry
about opening connections everywhere, passing them around....I dont
think its unreasonable that SA does some scope management. and of
course you could say to everyone "well just write wrappers" for all
that, but then we get into that whole __getattr__ thing that is so
inefficient. plus youll have an endless parade of people complaining
that "SQLAlchemy is too hard" / "SQLAlchemy requires you to write a
whole framework around it just to use it" etc. it has to be very
very simple for simple things...it doesnt want to force verbosity
when its not really required. what we're doing now is adding better
capabilities for verbosity for those that prefer/require it.
the whole thing is not "magic", its just objects that know how to
bind themselves to a resource to get something done. so now we're
making all the binding optional.
# table bound to an engine
t = Table('mytable', engine, ...)
t.select().execute()
# table not bound to anything
t = Table('mytable', None, ...)
# execute via using()
t.select().using(engine).execute()
# ...or with the keyword argument, sure...
t.select(engine=engine).execute()
# but when you do that, you really have this:
s = t.select(engine=engine)
# s is bound to an engine ! theres that magic again !
so anyway, heres the part youre not going to like (or....the next
part you wont like...)...this is just the idea I have so far but
havent completed it. the engine youre passing around to using() is
now just an AbstractEngine (seeking a better name)...its just a thing
that knows how to compile statements and execute them. which can
be....the SQLEngine we pass around, which knows how to pull from the
pool and execute statements....or....a ConnectionProxy that
represents just one specific connection context ! well geez why
more of this rubbery API stuff ? because say it only took the
connection and tried to be more rigid about argument types, like a
Java API would do it. then you will see, endlessly throughout an
application:
table.select(conn = engine.connect()).execute()
or even:
conn = engine.connect()
try:
conn.execute(table.select())
conn.execute(table.update(...))
finally:
conn.close()
which at first glance may seem like, hey thats a great, traditional
API! but then remember that we're doing Python, not J2EE....then you
might see it as just relentlessly and heartlessly verbose. What you
have up there is raw JDBC with a little bit of Python niceness, or
just some thin layer over DBAPI. It is either a total pain in the
ass to write verbosity like that all over an app, or you are forced
to write your own frameworks each time to relegate the repetetive
detail of patterns like the above to some central hidden-away
location. Well I still dont think SA is a "framework" (since we know
what scorn that will attract) but geez it has to do more than that
example above. everyone whos advanced will just write a wrapper
around the connect()s and probably the select()/execute() methods so
that it just pulls in an engine associated with the table, and
everyone whos not advanced will just blog and complain that SA is way
too hard to use and unnecessarily verbose. its just not Python to me !
Yes. And it's fine if a table needs a Schema as its container. Just
so the schema doesn't tie the table to a particular engine.
Although to complete the analogy between Table and Column for
Schema and Table it should be constructed like this:
schema = Schema('myschema',
Table('table_1', columns...),
Table('table_2', columns...),
...
)
I have a similar reaction to this....its completely consistent with
itself but not really practical. the current schema construction is
modeled after the typical experience working directly with a database
command line. there is a Table() syntax with column specs inside of
it, but schema selection is usually just determined by your initial
connection, or maybe a single "use" statement. theres a certain
"feel" its trying to maintain. you could force people to get to
their tables via "myschema.t.tablename" but at that point youre just
beating them over the head with how "perfectly consistent" the whole
thing is.
I think i feel the need to provide somewhat flexible interfaces to
these things since its the way I would want to use it ! basically
if theres any structures I know i will write every single time id
build an application with SA, like objects that can be bound to
different kinds of "execution contextual" objects, then Im going to
make those structures part of the library to start with.
anyway, while we still arent seeing quite the same vision yet, the
whole "de-enginification" of everything is underway which is a lot
closer to what youve suggested, all the binding and scoping you
dislike will be optional and less emphasized....and once thats
complete, we can visit again APIs that are still too ambiguous, and
we will have more ability to hone it down even more, including things
like using() vs. keyword arguments, connections vs. engines, and all
that stuff.
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users