Is the __enter__ and __exit__ behavior for connection objects specified in the Python database API?

Background

I recently discovered the Python keyword withand began to see its potential usefulness for more beautifully handling some scripts in which I previously used constructors try: ... finally: .... I immediately decided to try it on the MySQLdb connection object in some code that I wrote.

I did not read the information about how __enter__and __exit__behave in the implementation of Python Database API-interfaces, and naively expected that the behavior will be similar to the behavior of file objects - everything that I expected was to leave for the call connection.close().

Imagine my confusion with this behavior:

>>> with util.get_db_connection() as conn:
...     print conn
... 
<MySQLdb.cursors.Cursor object at 0xb6ca8b4c>

get_db_connection()returns a MySQLdb connection object, but the method of __enter__this connection object returns a cursor object, not the connection object itself, as I expected, as __enter__they __exit__work for file objects. I think I should have done with util.get_db_connection() as cursor:, otherwise not using withat all.

Questions

Immediately this discovery makes you think about several things:

  • What else do the methods __enter__and __exit__objects MySQLdb connection? Is it __exit__magical to make or roll back changes for me if I don't explicitly ask for it? Is there something else unobvious that I should know?
  • Is this behavior the same for other Python database API executors (e.g. sqlite3, django or psycopg2)?
  • ? ctrl-f (PEP 249 - API Python v2.0) 'enter', 'exit' 'context " .
+5
2

DBAPI , Python.

, , ( ).

. __enter__ __exit__, , . , MySQL :

connection = util.get_db_connection()

with connection as cursor:
    cursor.execute(...)

# connection commit is issued if no exceptions were raised.

sqlite3 - ; , __enter__:

con = sqlite3.connect(":memory:")
with con:
    cursor = con.cursor()
    # or use the connection directly
    con.execute(...)

, self __enter__.

+15

. __enter__ . https://github.com/PyMySQL/mysqlclient-python/blob/master/MySQLdb/connections.py

__enter__ self.cursor().

cursor Connection.

0

All Articles