如下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語句。