pyodbc是Python包,使用ODBC驅動器來連接SQL Server數據庫,pyodbc的基本類型是Connection,Cursor和Row,其中,Connection表示客戶端和數據庫的連接,並用於提交事務;Cursor表示向數據庫發送的查詢請求,Row表示獲取的結果集。
從微軟官方文檔來看,更推薦使用pyodbc來操作SQL Server數據庫。
一,ODBC驅動程序
要使用pyodbc連接SQL Server數據庫,必須安裝SQL Server數據庫的ODBC 驅動程序:
Install the Microsoft ODBC Driver for SQL Server on Windows,
當前的版本是Microsoft ODBC Driver 17,支持從SQL Server 2008到當前最新的SQL Server 2019版本。
{ODBC Driver 17 for SQL Server}
Microsoft ODBC Driver for SQL Server 是一個動態鏈接庫(DLL),包含run-time支持庫,使得程序可以使用native-code API連接到SQL Server數據庫。
使用pyodbc連接數據庫的基本操作,連接數據庫,執行查詢,並遍歷查詢結果:
import pyodbc # Specifying the ODBC driver, server name, database, etc. directly cn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass') # Create a cursor from the connection cursor = cn.cursor() #Selecting Some Data cursor.execute("select user_id, user_name from users") rows = cursor.fetchall() for row in rows: print(row.user_id, row.user_name) cn.close()
二,連接對象
連接對象代表Python和數據庫的連接,通過connect()函數來創建連接對象,連接對象通過ODBC驅動程序來訪問SQL Server數據庫:
cn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=mine;UID=user;PWD=pwd')
1,連接對象的屬性
cn.autocommit 是連接對象的一個屬性,默認情況下,連接對象是不會自動提交的,該屬性的值是False。在執行完成查詢請求之后,需要顯示提交。
如果設置autocommit為True,那么設置連接為自動提交模式:
cn.autocommit = True
cn.timeout, 用於設置超時時間,單位是秒,默認值是0,表示不限制時間。
2,連接對象可以創建Cursor對象
mycursor = cn.cursor()
3,連接對象提交或回滾事務
如果Cursor對象執行的是更新操作,比如執行UPDATE、DELETE或INSERT等更新操作,那么必須通過連接對象來顯式提交事務;如果執行的更新操作失敗,連接對象必須顯式回滾事務。如果Cursor對象執行的SELECT操作,不需要提交事務或者回滾事務。
cn.commit()
cn.rollback()
4,關閉連接對象
當關閉連接時,任何未提交的查詢語句都會回滾,更新操作的結果將會丟失。當連接對象被刪除,特別是超出作用域時,連接會自動關閉,但是,推薦顯式關閉連接。
cn.close()
三,Cursor對象
Cursor對象用於管理每個fetch操作的上下文,Cursor對象通過Connection對象來創建。
1,執行SQL語句
Cursor調用execute()函數來執行SQL語句:
execute(sql, *parameters)
executemany(sql, *params)
execute()函數只執行一次SQL語句,可以向SQL語句傳遞參數,傳參的格式有以下兩種:
# standard cursor.execute("select a from tbl where b=? and c=?", (x, y)) # pyodbc extension cursor.execute("select a from tbl where b=? and c=?", x, y)
executemany()可以對每組參數執行相同的SQL語句,
params = [ ('A', 1), ('B', 2) ] cursor.executemany("insert into t(name, id) values (?, ?)", params)
該語句等價於執行execute()函數兩次:
params = [ ('A', 1), ('B', 2) ] for p in params: cursor.execute("insert into t(name, id) values (?, ?)", p)
如果設置cursor.fast_executemany = True,可以提高executemany()函數的性能,該屬性默認是False。
2,fetch結果
從cursor對象中獲取單行:
cursor.fetchone()
從cursor對象中獲取多行:
cursor.fetchone(size=1)
從cursor對象中獲取所有行:
cursor.fetchall()
3,跳到下一個結果集
此方法將使Cursor對象跳至下一個可用結果集,並丟棄當前結果集中的所有剩余行。 如果沒有更多結果集,則該方法返回False。 否則,它將返回True,隨后對fetch方法的調用將返回下一個結果集中的行。
如果執行返回多個結果的存儲過程,那么主要使用此方法。
cursor.nextset()
4,關閉連接
在不再需要cursor時,請使用關閉Cursor對象。
cursor.close()
如果試圖訪問已經被關閉的cursor,程序將會出錯。Cursor對象會在被刪除或者超出作用域時自動關閉。
四,Row對象
Row對象調用fetch函數返回的一行數據,row對象的值可以被替換,從同一個select語句中返回的row對象共享內存。
row對象可以通過索引來訪問數據,也可以通過列名來訪問數據:
cursor.execute("select album_id, photo_id from photos where user_id=1") row = cursor.fetchone() print(row.album_id, row.photo_id) print(row[0], row[1]) # same as above, but less readable
fetchone()函數返回的是單行Row對象,fetchmany()函數 或這fetchall()函數返回的rows對象的列表:
cursor.execute("select album_id, photo_id from photos where user_id=1") rows = cursor.fetchall() for row in rows: row.album_id=1
row.photo_id=1001
五,上下文管理器
Connection對象和Cursor對象都支持Python的上下文管理(Context manager),使用with語句來自動關閉Connection對象和Cursor對象,並調用Connection對象的commit()函數來提交查詢。
1,Connection對象的上下文管理器
Connection對象的上下文管理器,不僅自動關閉連接,還會提交查詢:
with pyodbc.connect('mydsn') as cnxn: do_stuff #等價於 cnxn = pyodbc.connect('mydsn') do_stuff if not cnxn.autocommit: cnxn.commit()
2,Cursor對象的上下文管理器
Cursor對象的上下文管理器,會自動關閉Cursor,還會提交查詢:
with cnxn.cursor() as crsr: do_stuff #等價於 crsr = cnxn.cursor() do_stuff if not cnxn.autocommit: cnxn.commit()
3,使用上下文管理器來查詢結果
import pyodbc # Specifying the ODBC driver, server name, database, etc. directly with pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass') as cn: # Create a cursor from the connection with cn.cursor() as cursor: #Selecting Some Data cursor.execute("select user_id, user_name from users") rows = cursor.fetchall() for row in rows: print(row.user_id, row.user_name)
4,使用上下文管理器來執行更新操作
在執行更新操作,需要顯式提交事務
import pyodbc with pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass') as cn: try: cn.autocommit = False with cn.cursor() as cursor: params = [ ('A', 1), ('B', 2) ] cursor.executemany("insert into t(name, id) values (?, ?)", params) except pyodbc.DatabaseError as err: cn.rollback() else: cn.commit() finally: cn.autocommit = True
六,調用存儲過程
pyodbc 使用{call ...}來調用存儲過程,調用存儲過程的格式如下:
cursor.execute("{CALL usp_NoParameters}")
params = (14, "Dinsdale") cursor.execute("{CALL usp_HaveParammeters (?,?)}", params)
參考文檔: