M.-A. Lemburg wrote:
Chris Clark wrote:
M.-A. Lemburg wrote:
Chris Clark wrote:
Hi All,
I was discussing with someone today autocommit support and found an area
of pep-249 where I think we could improve the wording (and the spec):
http://www.python.org/dev/peps/pep-0249/
.....
.commit()
Commit any pending transaction to the database. Note
that
if the database supports an auto-commit feature, this must
be initially off. An interface method may be provided to
turn it back on.
.....
It is the last sentence that I'm looking at:
An interface method may be provided to turn it back on.
Comments:
* The "may" clearly marks this as an optional interface (and I'm
happy about that).
* It would be helpful to make clear what the interface method would
be so module authors can implement this consistently
* if autocommit can be turned on in a connection, there should have
a way to turn it off again
...
Comments?
mxODBC and mxODBC Connect will support a writable connection
attribute connection.autocommit to turn the feature on/off.
This works by assigning a boolean to the attribute. The
attribute also allows for an easy way to check whether autocommit
is active or not.
They both already support doing this via the (non-standard) DB-API
extension connection.setconnectoption() method.
From an API perspective, using an attribute is the right
and user-friendly approach. My only gripe with this is the fact,
that querying or setting the attribute can cause exceptions,
which you'd normally only expect from function/method calls.
Other than that I'm +1 on adding the attribute as standard
DB-API 2.0 extension.
Thanks M.A..
It looks like we are heading towards a consensus on an exception being
used (when mid transaction and autocommit on is requested). So we should
document that, I'm inclined to be a little whishy-washy and have a short
line along the lines of:
If an attempt is made to enable autocommit mid transactions this is
likely to cause a DBI exception, the exception raised may vary between
drivers/backends but will be a sub-class of driver.Error.
I actually like the way ODBC handles these cases:
* Turning on autocommit has the same effect as doing a .commit()
and then proceeding in autocommit mode.
* Turning off autocommit causes a new transaction to start.
but I guess we cannot require this from database modules, since
the semantics are usually defined by the database backend and not
the client lib or driver.
Aghhhh! ;-) That's what I initial sent out in my first proposal.
I think the "switching on autocommit, causes a commit" behavior is easy
to document and easy to implement. The driver could easily issue the
commit under the covers when autocommit is requested. I.e. it seems
reasonable for the driver to over ride the backend behavior to provide a
consistent interface across all backends. I'm not clear if the exception
approach can be implemented consistently. DBI drivers already have to
provide a consistent approach to transactions by not needing a "begin
transaction" call for users.
I'd like to try and cover the case mentioned above, where "*querying* or
setting the attribute can cause exceptions". Is this likely? If so we
should document that with a one liner too.
It's not likely, but can happen, e.g. if the connection to the
database is lost or the database doesn't support transactions or
if the backend doesn't support transactions (turning autocommit
off would then raise an exception).
That makes sense, I have to confess I'd been envisioning the driver
keeping track of the auto commit state and assuming that if the user
sent a cursor.execute('set auto commit on') it was reasonble for the
driver to not know about it. Obviously querying the layer below would
avoid that.
Thanks for explaining that, I'm glad you did but I've changed my mind
about documenting it :-)
I'd like to steal your wording for documentation, I've only changed the
first few words:
---------
A connection may optionally support a writable connection
attribute connection.autocommit to turn the feature on/off.
This works by assigning a boolean to the attribute. The
attribute also allows for an easy way to check whether autocommit
is active or not.
If an attempt is made to enable autocommit mid transactions this is
likely to cause a DBI exception, the exception raised may vary between
drivers/backends but will be a sub-class of driver.Error. A driver may
choose to implement autocommit manually (that is, manually issue commits
at the end of each cursor operation), to raise an exception if mid
transaction, or pass the autocommit request to the backend and raise an
exception for errors that the backend raises.
---------
I'm not sure about that last paragraph. The exception raising
part should really just be about turning autocommit on/off, not about
the way exceptions are raised as a result of the autocommit
implementation during cursor operations.
I not fond of it either :-( possibly for different reasons. The behavior
I described above is not clearly documented, I'm not sure if all
backends can/will raise an error. This is partially why I suggested
implicit commits as this is much easier for a user to grok.
Chris
_______________________________________________
DB-SIG maillist - DB-SIG@python.org
http://mail.python.org/mailman/listinfo/db-sig