Hut8
Hut8

Reputation: 6342

Python MySQLdb "with" syntax and DictCursor

I'm trying to use a DictCursor with a with block. I would think that by using:

with MySQLdb.connect(...) as c:

c would be a connection object, because that's what connect() returns. But alas, it is not! All of a sudden, c is a cursor! While this is usually convenient, I really like using a DictCursor - is this not designed that way at all? Enclosing the DictCursor as the "scoped object" causes an error (__exit__ wasn't defined)

Upvotes: 1

Views: 1843

Answers (3)

quickes
quickes

Reputation: 506

My fix for raw sql with sqlalchemy

if self.engine.url.drivername == 'mysql+pymysql':
    from pymysql.cursors import SSDictCursor
    connection = self.engine.raw_connection()
    cursor = connection.cursor(cursor=SSDictCursor)
elif self.engine.url.drivername == 'mysql+mysqldb':
    import MySQLdb.cursors
    connection = self.engine.raw_connection()
    cursor = connection.cursor(cursorclass=MySQLdb.cursors.DictCursor)
else:
    connection = self.engine.raw_connection()
    cursor = connection.cursor()

or use when create connection

connect_args=dict(cursorclass=MySQLdb.cursors.DictCursor)

Upvotes: 0

lisnb
lisnb

Reputation: 157

According to the definition of the Connection in MySQLdb here line 254 of connections.py, Connection.cursor() will return an instance of Connection.cursorclass:

def cursor(self, cursorclass=None):
    """
    Create a cursor on which queries may be performed. The
    optional cursorclass parameter is used to create the
    Cursor. By default, self.cursorclass=cursors.Cursor is
    used.
    """
    return (cursorclass or self.cursorclass)(self)

so, I guess if you initialize the connection with the argument "cursorclass", and set it to MySQLdb.cursors.DictCursor, like:

dbconn = MySQLdb.connect(cursorclass=MySQLdb.cursors.DictCursor)

when it comes

def __enter__(self):
    if self.get_autocommit():
        self.query("BEGIN")
    return self.cursor()

it will return a dict cursor.

Upvotes: 2

thikonom
thikonom

Reputation: 4267

c is a cursor because that's what is returned from the __enter__ method of the context manager.
If you browse Mysqldb's source code, you'll be able to see in line 245 of connections.py:

def __enter__(self): return self.cursor()

As for DictCursor, it does not support context management.

Upvotes: 1

Related Questions