[DB-SIG] Use of context managers with DB API 2

M.-A. Lemburg mal at egenix.com
Sat Nov 3 20:56:52 CET 2012


On 02.11.2012 10:53, Christoph Zwerschke wrote:
> ...
> What I find a bit ugly about this approach is that now the context managers of connections and
> cursors behave differently, and that code written using these context managers is not
> self-explanatory. If connections and cursors would just have closing context managers, and
> connections had an extra "transaction" member that is a context manager for handling the
> transaction, the code would be more readable and explicit which is better than implicit:
>
>     with dbapi2.connect(...) as con:
>         with con.transaction:
>             with con.cursor() as cur:
>                 cur.execute("insert into debit(amount) values (-100)")
>                 cur.execute("insert into credit(amount) values (100)")
>         with con.transaction:
>             with con.cursor() as cur:
>                 cur.execute("insert into debit(amount) values (-200)")
>                 cur.execute("insert into credit(amount) values (200)")
>

The described use of connections as context managers is already
implemented in several database modules and so I'm not sure whether
it's worth adding an extra attribute to connections would really
help.

Also note that people would likely start to think that they'd
somehow gain access to a separate transaction object by using
the extra attribute, which is not the case, since the connection
logically encapsulates the transaction.

Another nit I have with connections being used as context managers
is that the code reads as if a transaction is started at the
beginning of the block and ended when leaving it, but in reality,
this is not the case.

That said, using connections as context managers in the described
way is popular and probably already a standard practice, so I
guess it's better to standardize on it and document it properly,
rather than leaving it open for interpretation - even if just to
settle on one interpretation.

> Or, when using the shortcut methods:
> 
>     with dbapi2.connect(...) as con:
>         with con.transaction:
>             con.execute("insert into debit(amount) values (-100)")
>             con.execute("insert into credit(amount) values (100)")
>         with con.transaction:
>             con.execute("insert into debit(amount) values (-200)")
>             con.execute("insert into credit(amount) values (200)")

The "shortcut" methods you describe were explicitly removed when moving
from DB-API 1.0 to 2.0, so it's not a good idea to reintroduce them :-)

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source  (#1, Nov 03 2012)
>>> Python Projects, Consulting and Support ...   http://www.egenix.com/
>>> mxODBC.Zope/Plone.Database.Adapter ...       http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/
________________________________________________________________________

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611
               http://www.egenix.com/company/contact/


More information about the DB-SIG mailing list