如下Python操作数据库方法,使用上下文管理器管cursor。
def main():
conn = get_conn(....)
try:
create_table(conn)
insert_data(conn, 1, 'zhangsan', 20)
insert_data(conn, 2, 'lisi', 21)
with conn as cur:
cur.execute("select * from student")
rows = cur.fetchall()
for row in rows:
print(row)
finally:
if conn:
conn.close()
为什么使用with语句的表达式是一个Connection对象,但是返回的却是一个Coursor对象?
。在MySQLdb的源码中,Connection类定义了__enter__方法和__exit__方法。它们的实现如下:
class Connection(_mysql.connection):
def __enter__(self):
if self.get_autocommit():
self.query("BEGIN")
return self.cursor()
def __exit__(self, exc, value, tb):
if exc:
self.rollback()
else:
self.commit()
通过这段源码我们知道,虽然with语句的表达式是一个Connection对象,但是,Connection类的__enter__方法中返回的的确是一个Cursor对象。虽然这种实现方式有一点隐晦,但是,通过这种方式,我们就不用显示地创建Cursor对象了。通过这段源码可以看到,在一个Cursor中执行的SQL语句组成了一个事务。在执行这个事务的SQL语句过程中,如果出现了异常,则回滚整个事务,如果没有出现异常,则提交整个事务。也就是说,在Python中,我们一般不会显示地调用commit方法和rollback方法,而是通过上下文管理器来执行SQL语句。