1. 程式人生 > >Python與數據庫[1] -> 數據庫接口/DB-API -> 通用標準

Python與數據庫[1] -> 數據庫接口/DB-API -> 通用標準

mssql cal store 取出 .exe med 入參 desc 主機

數據庫接口 / DB-API


在Python中,數據庫是通過適配器(Adaptor)來連接訪問數據庫的,適配器通常與數據庫客戶端接口(通常為C語言編寫)想連接,而不同的適配器都會盡量滿足相同的DB-API標準。

為了保證不同數據庫的數據庫接口能夠通用於適配器,以減少使用不同數據庫接口是需要對代碼進行大幅改動,Python的DB-SIG(數據庫特殊興趣小組)制定了DB-API的標準,該API為不同的關系數據庫提供了一致的接口,使得使用不同數據庫的代碼間移植變得更加簡單。數據庫接口目前的版本為DB-API(2.0),可前往Python官網查看最新版本。

通用標準 / General Standard

對於任意的數據庫適配器db,需要提供至少以下幾項通用標準,以保證可移植性。

1 屬性 / Attribute

1.1 apilevel屬性

屬性調用: al = db.apilevel

屬性功能: 返回當前適配器支持的DB-API版本

屬性參數: al

al: str類型,目前支持"1.0"和"2.0"兩種,如果該適配器未指定,則假定為"1.0"

1.2 threadsafety屬性

屬性調用: tsf = db.threadsafety

屬性功能: 返回當前適配器支持的線程安全等級

屬性參數: tsf

tsf: int類型,線程安全等級

threadsafety

Meaning

0

Threads may not share the module.

1

Threads may share the module, but not connections.

2

Threads may share the module and connections.

3

Threads may share the module, connections and cursors.

1.3 paramstyle屬性

屬性調用: psy = db.paramstyle

屬性功能: 返回當前適配器支持的參數風格

屬性參數: psy

psy: str類型,參數風格的說明

paramstyle

Meaning

qmark

Question mark style, e.g. ...WHERE name=?

numeric

Numeric, positional style, e.g. ...WHERE name=:1

named

Named style, e.g. ...WHERE name=:name

format

ANSI C printf format codes, e.g. ...WHERE name=%s

pyformat

Python extended format codes, e.g. ...WHERE name=%(name)s

2 函數 / Function

2.1 connect ()函數

函數調用: cnx = db.connect/Connection/Connect(*args, **kwargs)

函數功能:生成一個數據庫的連接對象

傳入參數: args, kwargs

host: str類型,連接的主機地址,未傳入或‘localhost’都將連接本地數據庫

user: str類型,登入數據庫的用戶名

password/passwd: str類型,登錄數據庫的密碼

database/db: str類型,使用的數據庫schema名稱

返回參數: cnx

cnx: obj類型,一個數據庫連接實例

3 / Class

3.1 Connection

類實例化:cnx = db.connect/Connection/Connect(*args, **kwargs)

類的功能:用於聯系數據庫API的連接對象

傳入參數: args, kwargs

host: str類型,連接的主機地址,未傳入或‘localhost’都將連接本地數據庫

user: str類型,登入數據庫的用戶名

password/passwd: str類型,登錄數據庫的密碼

database/db: str類型,使用的數據庫schema名稱

返回參數: cnx

cnx: obj類型,一個數據庫連接實例

3.1.1 close()方法

函數調用: cnx.close()

函數功能:關閉數據庫連接

傳入參數:

返回參數:

3.1.2 commit()方法

函數調用: cnx.commit()

函數功能:提交當前事務,通常當命令具有執行修改等性質的時候需要此函數完成確認

傳入參數:

返回參數:

3.1.3 rollback()方法

函數調用: cnx.rollback()

函數功能:取消當前事務

傳入參數:

返回參數:

3.1.4 cursor()方法

函數調用: cur = cnx.cursor()

函數功能:使用該連接對象創建返回一個遊標對象

傳入參數:

返回參數: cur

cur: obj類型,遊標對象的實例,可以通過遊標進行操作數據庫

3.2 Cursor

類實例化:cur = cnx.cursor()

類的功能:一個用於操作數據庫的遊標對象

傳入參數: args, kwargs

host: str類型,連接的主機地址,未傳入或‘localhost’都將連接本地數據庫

user: str類型,登入數據庫的用戶名

password/passwd: str類型,登錄數據庫的密碼

database/db: str類型,使用的數據庫schema名稱

返回參數: cnx

cnx: obj類型,一個數據庫連接實例

3.2.1 arraysize屬性

屬性調用: as = cur.arraysize

屬性功能: 表示使用fetchmany()方法時,一次性取出的結果行數,默認為1

屬性參數: as

as: int類型,一次性fetch的行數

3.2.2 connection屬性

屬性調用: cnx = cur.connection

屬性功能: 返回生成該遊標的connection實例

屬性參數: cnx

cnx: obj類型,生成當前遊標的連接實例

3.2.3 description屬性

屬性調用: dsp = cur.description

屬性功能: 返回當前遊標的活動狀態

屬性參數: dsp

dsp: tuple/NoneType類型,一個7元素元組描述當前狀態

3.2.4 lastrowid屬性

屬性調用: rid = cur.lastrowid

屬性功能: 上次修改行的ID,不支持則返回None

屬性參數: rid

rid: int/NoneType類型,修改的行ID

3.2.5 rowcount屬性

屬性調用: roc = cur.rowcount

屬性功能: 上次execute*()修改行所影響的行數

屬性參數: roc

roc: int類型,修改影響的行數

3.2.6 close()方法

函數調用: cur.close()

函數功能:關閉遊標

傳入參數:

返回參數:

3.2.7 execute()方法

函數調用: [r =] cur.execute(query, args=None)

函數功能:執行數據庫命令

傳入參數: query, args

query: str類型,執行的SQL命令行

args: sequence/mapping類型,query使用的參數

返回參數: r

r: int類型,執行所影響的行數

3.2.8 executemany()方法

函數調用: [r =] cur.executemany(query, args)

函數功能:執行多條數據庫命令,類似execute()和map()的結合

傳入參數: query, args

query: str類型,執行的SQL命令行

args: sequence/mapping類型,query使用的參數

返回參數: r

r: int類型,執行所影響的行數

3.2.9 fetchone()方法

函數調用: r = cur.fetchone()

函數功能:獲取查詢結果的下一行

傳入參數:

返回參數: r

r: tuple類型,查詢結果的下一條信息的元組

3.2.10 fetchmany()方法

函數調用: r = cur.fetchmany(size=cursor.arraysize)

函數功能:獲取查詢結果的下n行,默認為arraysize的設置值

傳入參數: size

size: int類型,查詢下n行

返回參數: r

r: tuple類型,查詢結果的下n條信息的元組

3.2.11 fetchall()方法

函數調用: r = cur.fetchall()

函數功能:獲取查詢結果的所有(剩余)行

傳入參數:

返回參數: r

r: tuple類型,查詢結果的所有剩余信息元組

4 補充知識 / Complement Knowledge

4.1 CursorConnection

在MySQL中,Connection生成的實例利用query函數已經可以完成基本的SQL數據庫操作,而Cursor的execute功能與其類似,但是引入Cursor可以使在不必要的時候銷毀Cursor節省資源占用,同時無需斷開連接。參考 stack overflow 鏈接。

5 應用實例 / Complement Knowledge

下面的例子中將構建一個簡單的通用適配器驅動,其中實現了各種適配器通用的函數方法。

 1 class SqlConnector():
 2     def __init__(self, adaptor):
 3         self.adaptor = adaptor
 4         self.result = None
 5         # Check Adaptor info
 6         print(Adaptor %s apply DB-API %s, thread safety: %d, parameter style: %s % (adaptor.__name__, adaptor.apilevel, adaptor.threadsafety, adaptor.paramstyle))
 7 
 8     # Login by user name and password
 9     def login(self, **kwargs):
10         # Create a connection obj
11         self.cnx = self.adaptor.connect(**kwargs)
12 
13     def logoff(self):
14         self.cnx.close()
15 
16     def query_sql(self, sql, show=True):
17         # Method one: Use Connection
18         ‘‘‘
19         self.cnx.query(sql)
20         self.result = self.cnx.store_result()
21         r = self.result.fetch_row(0, )
22         self.cnx.commit()
23         ‘‘‘
24         # Method two: Use Cursor
25         cur = self.cnx.cursor()
26         cur.execute(sql)
27         r = cur.fetchall()
28         self.cnx.commit()
29         cur.close()
30 
31         if show:
32             splt = \n + ((len(sql)+6)*-)
33             msg = ‘‘.join((\n{: ^10} | ).format(str(i)) if x.index(i) == 0 else ({: ^10} | ).format(str(i)) for x in r for i in x)
34             s = ({:-^%d}%(len(sql)+6)).format(sql) + msg + splt
35             print(s)
36         return (i for x in r for i in x)
37 
38     def exec_sql(self, sql):
39         cur = self.cnx.cursor()
40         cur.execute(sql)
41         self.cnx.commit()
42         cur.close()
43 
44     def commit(self):
45         self.cnx.commit()
46 
47 if __name__ == __main__:
48     import MySQLdb
49     import pymssql
50     r = input(Please choose your adaptor:\n(M)MySQL\n(S)MsSQL\n)
51     adaptor_list = {M: MySQLdb, S: pymssql}
52     c = SqlConnector(adaptor_list[r.upper()])
53     # No local MSSQL server
54     c.login(host=localhost, user=root, password=root)
55     c.logoff()

第 1-6 行,建立適配器的類,在初始化用利用適配器的通用屬性查看適配器的基本信息,包括適配器名稱,使用的DB-API等級,線程安全等級,參數風格等。

第 8-14 行,定義登錄退出函數,登錄時創建連接實例,退出時關閉。

第 16-36 行,定義請求函數,對於數據庫的操作有兩種方式實現,第一種是使用Connection,第二種是使用Cursor,同時對請求的結果進行顯示。

第 38-45 行,定義執行函數,用於執行SQL的命令語句,對於有修改性質的語句必須commit後才能在數據庫端生效。

第 47-55 行,最後僅對數據庫進行登錄退出測試,由於本地僅安裝了MYSQL,沒有安裝MSSQL的服務器,因此無法登錄MSSQL。

運行結果如下

Please choose your adaptor:
(M)MySQL
(S)MsSQL
M
Adaptor MySQLdb apply DB-API 2.0, thread safety: 1, parameter style: format

參考鏈接


https://www.python.org/dev/peps/pep-0249/

https://stackoverflow.com/questions/10660411/difference-between-cursor-and-connection-objects/10660537#10660537

Python與數據庫[1] -> 數據庫接口/DB-API -> 通用標準