Python MySQLdb“with”语法和DictCursor

时间:2013-02-14 17:14:00

标签: python mysql-python

我正在尝试将DictCursorwith块一起使用。我认为通过使用:

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

c将是一个连接对象,因为这是connect()返回的内容。但唉,事实并非如此!突然间,c是一个光标!虽然这通常很方便,但我真的很喜欢使用DictCursor - 这根本不是这样设计的吗?将DictCursor封装为“范围对象”会导致错误(__exit__未定义)

3 个答案:

答案 0 :(得分:2)

根据MySQLdb中的连接定义line 254 of connections.py,Connection.cursor()将返回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)

所以,我想如果用参数" cursorclass"初始化连接,并将其设置为MySQLdb.cursors.DictCursor,如:

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

来的时候

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

它将返回一个dict光标。

答案 1 :(得分:1)

c是一个游标,因为它是从上下文管理器的__enter__方法返回的内容。
如果您浏览Mysqldb的源代码,您将能够在line 245 of connections.py中看到:

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

至于DictCursor,它不支持上下文管理。

答案 2 :(得分:0)

我使用sqlalchemy修复原始sql

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()

或在创建连接时使用

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