pyodbc 操作SQL Server數據庫


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)

 

 

 

參考文檔:

pyodbc wiki


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM