第十三章 數據庫支持
本章討論Python數據庫API(一種連接到SQL數據庫的標準化方式),并演示如何使用這個API來執行一些基本的SQL。最后,本章將討論其他一些數據庫技術。
關Python支持的數據庫清單
Python數據庫API
標準數據庫API(DB API)
Python官方維基百科中的數據庫編程指南
全局變量
變量名 | 描述 |
---|---|
apilevel | 使用的Python DB API版本;是一個字符串常量,指出了使用的API版本。 |
threadsafety | 模塊的線程安全程度如何;是一個0~3(含)的整數。0表示線程不能共享模塊,而3表示模塊是絕對線程安全的。1表示線程可共享模塊本身,但不能共享連接,而2表示線程可共享模塊和連接,但不能共享游標。 |
paramstyle | 在SQL查詢中使用哪種參數風格;format’表示標準字符串格式設置方式(使用基本的格式編碼),如在要插入參數的地方插入%s。'pyformat’表示擴展的格式編碼,即舊式字典插入使用的格式編碼,如%(foo)s;'qmark’表示使用問號,'numeric’表示使用:1和:2這樣的形式表示字段(其中的數字是參數的編號),而’named’表示使用:foobar這樣的形式表示字段(其中foobar為參數名) |
異常
異常 | 超類 | 描述 |
---|---|---|
StandardError | 所有異常的超類 | |
Warning | StandardError | 發生非致命問題時引發 |
Error | StandardError | 所有錯誤條件的超類 |
InterfaceError | Error | 與接口(而不是數據庫)相關的錯誤 |
DatabaseError | Error | 與數據庫相關的錯誤的超類 |
DataError | DatabaseError | 與數據相關的問題,如值不在合法的范圍內 |
OperationalError | DatabaseError | 數據庫操作內部的錯誤 |
IntegrityError | DatabaseError | 關系完整性遭到破壞,如鍵未通過檢查 |
InternalError | DatabaseError | 數據庫內部的錯誤,如游標無效 |
ProgrammingError | DatabaseError | 用戶編程錯誤,如未找到數據庫表 |
NotSupportedError | DatabaseError | 請求不支持的功能,如回滾 |
連接和游標
要使用底層的數據庫系統,必須先連接到它,為此可使用名稱貼切的函數connect。接受多個參數,具體是哪些取決于要使用的數據庫。
函數connect的常用參數
參數名 | 描述 | 是否可選 |
---|---|---|
dsn | 數據源名稱,具體含義隨數據庫而異 | 否 |
user | 用戶名 | 是 |
password | 用戶密碼 | 是 |
host | 主機名 | 是 |
database | 數據庫名稱 | 是 |
函數connect返回一個連接對象,表示當前到數據庫的會話。
連接對象的方法
方法名 | 描述 |
---|---|
close() | 關閉連接對象。之后,連接對象及其游標將不可用 |
commit() | 提交未提交的事務——如果支持的話;否則什么都不做 |
rollback() | 回滾未提交的事務(可能不可用) |
cursor() | 返回連接的游標對象 |
游標對象的方法
名稱 | 描述 |
---|---|
callproc(name[, params]) | 使用指定的參數調用指定的數據庫過程(可選) |
close() | 關閉游標。關閉后游標不可用 |
execute(oper[, params]) | 執行一個SQL操作——可能指定參數 |
executemany(oper, pseq) | 執行指定的SQL操作多次,每次都序列中的一組參數 |
fetchone() | 以序列的方式取回查詢結果中的下一行;如果沒有更多的行,就返回None |
fetchmany([size]) | 取回查詢結果中的多行,其中參數size的值默認為arraysize |
fetchall() | 以序列的序列的方式取回余下的所有行 |
nextset() | 跳到下一個結果集,這個方法是可選的 |
setinputsizes(sizes) | 用于為參數預定義內存區域 |
setoutputsize(size[, col]) | 為取回大量數據而設置緩沖區長度 |
游標對象的屬性
名稱 | 描述 |
---|---|
description | 由結果列描述組成的序列(只讀) |
rowcount | 結果包含的行數(只讀) |
arraysize | fetchmany返回的行數,默認為1 |
類型
DB API構造函數和特殊值
名稱 | 描述 |
---|---|
Date(year, month, day) | 創建包含日期值的對象 |
Time(hour, minute, second) | 創建包含時間值的對象 |
Timestamp(y, mon, d, h, min, s) | 創建包含時間戳的對象 |
DateFromTicks(ticks) | 根據從新紀元開始過去的秒數創建包含日期值的對象 |
TimeFromTicks(ticks) | 根據從新紀元開始過去的秒數創建包含時間值的對象 |
imestampFromTicks(ticks) | 根據從新紀元開始過去的秒數創建包含時間戳的對象 |
Binary(string) | 創建包含二進制字符串值的對象 |
STRING | 描述基于字符串的列(如CHAR) |
BINARY | 描述二進制列(如LONG或RAW) |
NUMBER | 描述數字列 |
DATETIME | 描述日期/時間列 |
ROWID | 描述行ID列 |
SQLite和PySQLite
起步
導入模塊sqlite3來導入Python標準庫中的SQLit
import sqlite3#導入模塊sqlite3
conn = sqlite3.connect('beyond.db')#連接數據庫,若數據庫不存在則自動創建
curs = conn.cursor()#從連接獲得游標,這個游標可用來執行SQL查詢。
conn.commit()#在每次修改數據庫后都進行提交
conn.close()#關閉連接
數據庫應用程序示例
ABBREV.txt數據庫信息放在與程序同一個目錄下
ABBREV.txt
在文件ABBREV.txt中,每行都是一條數據記錄,字段之間用脫字符(^)分隔。
數字字段直接包含數字,而文本字段用兩個波浪字符(~)將其字符串值括起。
將這個ASCII文件中的數據轉換為SQL數據庫
1,創建并填充數據庫表
創建一個名為food的表
讀取文件ABBREV.txt并對其進行分析
通過調用curs.execute來執行一條SQL INSERT語句,從而將字段中的值插入數據庫中。
將數據導入數據庫
import sqlite3
def convert(value): if value.startswith('~'): return value.strip('~') if not value: value = '0' return float(value)conn = sqlite3.connect('food.db')
curs = conn.cursor()curs.execute('''
CREATE TABLE food (
id TEXT PRIMARY KEY,
desc TEXT,
water FLOAT,
kcal FLOAT,
protein FLOAT,
fat FLOAT,
ash FLOAT,
carbs FLOAT,
fiber FLOAT,
sugar FLOAT
)
''')
query = 'INSERT INTO food VALUES (?,?,?,?,?,?,?,?,?,?)'
field_count = 10
for line in open('ABBREV.txt'):fields = line.split('^') vals = [convert(f) for f in fields[:field_count]] curs.execute(query, vals)conn.commit()
conn.close()
當你運行這個程序時(文件ABBREV.txt和它位于同一個目錄),它將新建一個名為food.db的文件,其中包含數據庫中的所有數據。
2,搜索并處理結果
數據庫查詢程序
import sqlite3,sys
conn = sqlite3.connect('food.db')
curs = conn.cursor()
query = 'SELECT * FROM food WHERE ' + sys.argv[1]
print(query)
curs.execute(query)
names = [f[0] for f in curs.description]
for row in curs.fetchall(): for pair in zip(names, row): print('{}: {}'.format(*pair)) print()
小結
概念 | 解釋 |
---|---|
Python DB API | 這個API定義了一個簡單的標準化接口,所有數據庫包裝器模塊都必須遵循它,這讓編寫使用多個不同數據庫的程序更容易。 |
連接 | 連接對象表示到SQL數據庫的通信鏈路,使用方法cursor可從連接獲得游標。你還可使用連接對象來提交或回滾事務。使用完數據庫后,就可將連接關閉了。 |
游標 | 游標用于執行查詢和查看結果。可逐行取回查詢結果,也可一次取回很多(或全部)行。 |
類型和特殊值 | DB API指定了一組構造函數和特殊值的名稱。構造函數用于處理日期和時間對象,還有二進制數據對象;而特殊值用于表示關系型數據庫的類型,如STRING、NUMBER和DATETIME。 |
SQLite | 這是一個小型的嵌入式SQL數據庫,標準Python發行版中包含其Python包裝器,即模塊sqlite3。這個數據庫速度快、易于使用,且不要求搭建專門的服務器。 |
本章介紹的函數
函數 | 描述 |
---|---|
connect(…) | 連接到數據庫并返回一個連接對象 |