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

Reply via email to