daniel -
glad youre involved with this discussion since youre the "main guy"
besides me with regards to objectstore.begin/commit design :)
your API below looks very nice. but there are some issues and
questions:
cn = SQLEngine.connection(...) # get pooled connection
what is cn ? since it has begin/commit stuff that returns
SQLTransactions, it cant be just a striaght DBAPI connection. Right
now, the SQLSession object is most analgous to this, it is a
connection-holding object. The SQLEngine has already been detached
from its connections to a large degree, but it remains a "factory"
for new connections, as well as SQL compilers which are the
"connection-less" component to a particular type of database.
Note: the "explicit transaction model" does not perform database-
level nested transactions, which is a feature of some databases
that allows sub-units-of-work to be performed and committed/
rollbacked without affecting the outer transaction(s). Rather, it
is a pattern that uses a single database transaction while allowing
multiple levels of SA transactions to be started/committed with
only the outermost commit actually causing the database transaction
to be committed.
well, we need both kinds of nesting. this is one of the key
challenges here, in that there is nesting of transactions at the
lexical level with a depth counter, there is nesting of objectstore
"Sessions" that track lists of objects to be committed, and there is
real "nesting" that occurs via opening a second database connection.
people definitely need all three and I have complicated the API to
provide all of these features. So how would this proposed API
handle opening a second connection ?
SQLTransaction and SessionTransaction should strive to maintain a
simple, uniform interface. That will reduce confusion. In fact,
could they be combined into a single type? If not, why and what is
the difference?
One of the up-until-now cherished design goals here, which it seems
like you are looking to dilute, is that the objectstore/Session API
is 100% specific to SA's object relational mapper and is not required
in any way to just deal with SQL statements, SQL transactions, and
engines. I still think this separation is essential, SA must be a
"complete product" without the ORM/Session used at all; that way
other folks can build other kinds of ORMs or whatever on top of it.
Another major difference between Session/Engine is that the Engine
knows about a specific database; the Session does not. a Session can
commit objects across any number of databases in one shot. that was
why I proposed that session.begin_transaction() (named to avoid
conflicts with the old one, but if people dont mind the switch i can
go with begin()), actually sets up a "global transaction" that all
the various SQLEngines would join into as they are called within that
thread. this is more of a J2EE type of feature which can have a lot
of value.
i think the two things that are important to me right now are:
- changing objectstore.commit() to be a different name, probably
flush()
- either removing the words "begin"/"commit" from the objectstore
package totally, or if they are there, then they will correspond to a
real database transaction in some way.
thats the main thing I want to focus on.
Also a slightly more radical change (don't group it with the
transaction handling changes) would be to associate a connection
with a session rather than with an engine. The engine only knows
how to make new connections, it does not maintain a reference to
the connection (the Session does that), and it loses it's execute()
method (that's the Connection's job). The engine then becomes a
stateless object to assist the mapper in constructing database-
specific SQL statements, which is what Ian Bicking wanted. This is
how I see that API:
conn = engine.connect()
trans = conn.begin()
conn.execute("<raw sql>")
conn.execute(engine.create(mytable))
trans.commit()
OK that example is not entirely clear to me, do I now have to take
every ClauseElement construction and send it to a specific "conn"
every time now ? I.e. I can no longer say:
select([mytable]).execute()
since theres no "connection" present there ? are we looking to just
add an "execute(statement)" method to the existing "SQLSession"
object, allowing this:
engine.connect().execute(select([mytable])) ?
If you are looking for a stateless object to construct database-
specific SQL statements, there is the Compiler object which has been
there all along, and after Ian's SQLAPI announcement i made some
minor changes to support SQL construction without any engine....that
SA did not allow "connectionless SQL" has always been a strawman from
the start. Theres the ProxyEngine, and theres No Engine. There
hasnt really been any interest in pure SQL generation without ever
executing it either, but the general ability is there, introduced at
http://www.sqlalchemy.org/docs/
metadata.myt#metadata_adapting_primitives. As an example, I dont
have MS SQL Server installed at all but am able to run the SQL
construction unit test with the new MSSQL compiler.
anyway, since this is the more "radical" change, lets try to come up
with the less radical thing first, that is removing/clarifying the
words "begin" and "commit" from the objectstore package..thats really
all i want to get out of this.
-------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users