python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(九):數(shù)據(jù)庫客戶端 DB-API
一、DB-API概述
python支持很多不同的數(shù)據(jù)庫。由于不同的賣家服務(wù)器導(dǎo)致和數(shù)據(jù)庫通信的網(wǎng)絡(luò)協(xié)議各有不同。在python的早期版本中,每一種數(shù)據(jù)庫都帶有自己的python模塊,所有這些模塊以不同的方式工作,并提供不同的函數(shù)。這種方法不便于編寫能夠在多種數(shù)據(jù)庫服務(wù)器類型中運(yùn)行的代碼,于是DB-API庫函數(shù)產(chǎn)生。在DB-API中,所有連接數(shù)據(jù)庫的模塊即便是底層網(wǎng)絡(luò)協(xié)議不同,也會提供一個共同的接口。這一點(diǎn)和JAVA中的JDBC和ODBC類似。
DB-API下載地址:http://wiki.python.org/moin/DatabaseProgramming,目前版本是2.0,支持?jǐn)?shù)據(jù)庫包括IBM DB2、Firebird (and Interbase) 、Informix、Ingres、MySQL、Oracle 、PostgreSQL 、SAP DB (also known as "MaxDB") 、Microsoft SQL Server 、Sybase 等。
二、數(shù)據(jù)庫連接
1、PostgreSQL
有幾個模塊可以完成python與PostgreSQL的聯(lián)接,這里主要介紹使用psycopg。
下載地址是:http://initd.org/psycopg/download/。如果沒有PostgreSQL,可以從以下地址下載:http://www.postgresql.org/。(關(guān)于PostgreSQL的安裝等更加詳細(xì)的介紹,可以見http://wenku.baidu.com/view/8e32d10c6c85ec3a87c2c500.html。)連接PostgreSQL數(shù)據(jù)庫:
import psycopg2
print "connecting to test"##test為數(shù)據(jù)庫名
dbh=psycopg2.connect('dbname=test user=postgres')
print "connection successful"
2、MySQL
對于MySQL,python的接口是已知的MySQLdb或者M(jìn)ySQL-Python,下載地址:http://sourceforge.net/projects/mysql-python/。與PostgreSQL不同的是,MySQLdb connect()函數(shù)可以帶各種參數(shù),具體如下:
參數(shù) | 說明 |
user | 用戶名,默認(rèn)為當(dāng)前登錄用戶。 |
passwd | 用戶密碼,沒有默認(rèn)的。 |
db | 連接的數(shù)據(jù)庫名。 |
host | 數(shù)據(jù)庫主機(jī)名。 |
port | TCP端口,默認(rèn)是3306。 |
舉例,連接test數(shù)據(jù)庫:
import MySQLdb
print "connecting..."
dbh=MySQLdb.connect(db="test")
print "connection successful."
dbh.close()
三、簡單操作(以PostgreSQL為例)
這里以PostgreSQL為例介紹創(chuàng)建表、查詢表等操作。例子中數(shù)據(jù)庫名為test,用戶名為postgres,輸入一個表名,向表中插入數(shù)據(jù)并進(jìn)行查詢。具體如下,已進(jìn)行了注示:
import psycopg2
print "connecting to test"
dbh=psycopg2.connect('dbname=test user=postgres')
print "connection successful"
cur=dbh.cursor()#建立一個cursor對象,返回數(shù)據(jù)為字典形式
a=raw_input('table list:')#輸入表名
cur.execute("CREATE TABLE %s(myid integer UNIQUE,filename varchar(255))" %a)#生成表,包含一個字段filename
b=1c='201210310540'
cur.execute("INSERT INTO %s VALUES (%d,%s)"%(a,b,c))#向表中插入記錄b,c
cur.execute("SELECT * FROM %s " %a)#查詢表中內(nèi)容
rows=cur.fetchall()#獲得結(jié)果集中的所有行
for row in rows:
print row
dbh.commit()#以上對數(shù)據(jù)庫的操作事務(wù)生效
dbh.close()
1、事務(wù)
多數(shù)數(shù)據(jù)庫支持事務(wù),事務(wù)可以將多條對數(shù)據(jù)庫的改動放在一條命令中。在上面的例子中,當(dāng)未曾執(zhí)行commit()命令時,以上對數(shù)據(jù)庫的操作均不會生效。另外還有一個函數(shù)rollback(),這個函數(shù)可以有效的放棄上一次執(zhí)行commit()或者rollback()之后的改動。這個函數(shù)在發(fā)現(xiàn)錯誤,并想放棄已經(jīng)發(fā)出的事務(wù)時,非常有效。對于不支持事務(wù)的數(shù)據(jù)庫,改變會立刻執(zhí)行,commit()什么也不做,但rollback()會報錯。
2、效率
執(zhí)行事件的性能很大程序上取決于不同的服務(wù)器,一般來說,在每個單獨(dú)的命令后都提交是更新數(shù)據(jù)庫最慢的方法,但如果一次提交很大數(shù)據(jù)又會使服務(wù)器產(chǎn)生buffer溢出。因此,應(yīng)該合理處理提交的數(shù)量。
四、參數(shù)風(fēng)格
在上面的例子中,使用了printf()一樣的類型格式。但實際上,在DB-API中,不同的數(shù)據(jù)庫所支持的參數(shù)風(fēng)絡(luò)不同,必須選擇合適的方法,否則程序不會執(zhí)行。下面的方法,可以知道當(dāng)前所支持的類型格式。
>>> import psycopg2
>>> print psycopg2.paramstyle
pyformat這一結(jié)果可以看出,當(dāng)前支持pyformat格式。
針對DB-API說明書,以使用頻度由小變大的順序介紹:
qmark | 表示question-mark風(fēng)格。指令字符串中的數(shù)據(jù)的每一位都被用一個問號替換,參數(shù)以list或tuple的形式給出。例如:INSERT INTO ch14 VALUES (?, ?)。 |
format | 使用和printf()一樣的類型格式,不支持對于指定參數(shù)Python的擴(kuò)展名。它帶一個list或tuple來轉(zhuǎn)換。例如:INSERT INTO ch14 VALUES(%d, %s) |
numeric | 表示numeric風(fēng)格。指令字符串中的數(shù)據(jù)的每一位都被一個后面是數(shù)字的冒號替換(數(shù)字以1開始),參數(shù)以list或tuple的形式給出。例如:INSERT INTO ch14 VALUES(:1, :2) |
named | 表示named風(fēng)格。和numeric類似,但是在冒號后面用名稱取代數(shù)字。帶一個dictionary用來轉(zhuǎn)換。例如:INSERT INTO ch14 VALUES(:number, :text) |
pyformat | 支持Python風(fēng)格的參數(shù),帶dictionary用來轉(zhuǎn)換。例如:INSERT INTO ch14 VALUES(%(number)d, %(text)s)。 |
五、重復(fù)指令
1、execute和executemany()
例子:
將下面的數(shù)據(jù)插入到test數(shù)據(jù)庫中:
12 Twelve
13 Thirteen
14 Fourteen
15 Fifteen
(1)execute一條條插入
cur.execute("INSERT INTO test VALUES (12, 'Twelve')")
cur.execute("INSERT INTO test VALUES (13, 'Thirteen')")
cur.execute("INSERT INTO test VALUES (14, 'Fourteen')")
cur.execute("INSERT INTO test VALUES (15, 'Fifteen')")
這種方法過于低效。
(2)executemany()函數(shù)帶一個指令和一列指令運(yùn)行的記錄。列表上的每條記錄要么是一個list,要么是一個dictionary。
import psycopg2
print "connecting to test"
dbh=psycopg2.connect('dbname=test user=postgres')
print "connection successful"
cur=dbh.cursor()
rows = ({'num': 0, 'text': 'Zero'},
{'num': 1, 'text': 'Item One'},
{'num': 2, 'text': 'Item Two'},
{'num': 3, 'text': 'Three'})
cur.executemany("INSERT INTO test VALUES (%(num)d, %(text)s)", rows)
dbh.commit()
dbh.close()
executemany()主要的缺點(diǎn)是,在需要執(zhí)行指令前把所有的記錄放在內(nèi)存中。如果數(shù)據(jù)大的話,這就是一個問題,它會占有系統(tǒng)的所有內(nèi)存資源。如果executemany()不能滿足需要,那么除了execute()之外,還是有可能取得性能優(yōu)化的。根據(jù)DB-API說明,當(dāng)execute()被周期性調(diào)用時,數(shù)據(jù)庫后端可以執(zhí)行優(yōu)化。但是它的第一個參數(shù)必須指向同一個對象,而不是一個含有相同值的字符串,即在內(nèi)存中的同一個字符串對象。和executemany()一樣,這樣并不能保證優(yōu)化,并且也不能期望execute()運(yùn)行得比executemany()快。但是如果不能使用executemany(),這就是一個最好的選擇。
六、fetchall、fetchmany、fetchone獲取數(shù)據(jù)
fetchall(self):接收全部的返回結(jié)果行。
fetchmany(self, size=None):接收size條返回結(jié)果行.如果size的值大于返回的結(jié)果行的數(shù)量,則會返回cursor.arraysize條數(shù)據(jù)。
fetchone(self):返回一條結(jié)果行。
七、獲取metadata(元數(shù)據(jù))
元數(shù)據(jù)的英文名稱是“Metadata",它是“關(guān)于數(shù)據(jù)的數(shù)據(jù)”。如在上面的例子中,Metadata的結(jié)果為:
Column(name='id', type_code=23, display_size=None, internal_size=4, precision=None, scale=None, null_ok=None)
Column(name='filename', type_code=1043, display_size=None, internal_size=255, precision=None, scale=None, null_ok=None)
import psycopg2
print "connecting to bbstime"
dbh=psycopg2.connect('dbname=bbstime user=postgres')
print "connection successful"
cur=dbh.cursor()
cur.execute("SELECT * FROM asd")
for column in cur.description:
print column
dbh.close()
八、計算行數(shù)
方法有兩種,一種是用len(),一種是用rowcount。
import psycopg2
print "connecting to bbstime"
dbh=psycopg2.connect('dbname=bbstime user=postgres')
print "connection successful"
cur=dbh.cursor()
cur.execute("SELECT * FROM test")
rows=cur.fetchall()
print len(rows)#利用len來計算行數(shù)
print "rows:",cur.rowcount#利用rowcount來計算行數(shù)
dbh.close()
- Python udp網(wǎng)絡(luò)程序?qū)崿F(xiàn)發(fā)送、接收數(shù)據(jù)功能示例
- Python大數(shù)據(jù)之網(wǎng)絡(luò)爬蟲的post請求、get請求區(qū)別實例分析
- Python 網(wǎng)絡(luò)編程之UDP發(fā)送接收數(shù)據(jù)功能示例【基于socket套接字】
- 詳解Python3網(wǎng)絡(luò)爬蟲(二):利用urllib.urlopen向有道翻譯發(fā)送數(shù)據(jù)獲得翻譯結(jié)果
- Python下載網(wǎng)絡(luò)文本數(shù)據(jù)到本地內(nèi)存的四種實現(xiàn)方法示例
- Python爬蟲實例_城市公交網(wǎng)絡(luò)站點(diǎn)數(shù)據(jù)的爬取方法
- python網(wǎng)絡(luò)編程調(diào)用recv函數(shù)完整接收數(shù)據(jù)的三種方法
- python網(wǎng)絡(luò)編程之?dāng)?shù)據(jù)傳輸U(kuò)DP實例分析
- python如何獲取網(wǎng)絡(luò)數(shù)據(jù)
相關(guān)文章
Python錯誤NameError:name?'X'?is?not?defined的解決方法
這篇文章主要給大家介紹了關(guān)于Python錯誤NameError:name?‘X‘?is?not?defined的解決方法,這是最近工作中遇到的一個問題,文中通過實例代碼將解決的方法介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03pycharm部署django項目到云服務(wù)器的詳細(xì)流程
今天重點(diǎn)給大家介紹pycharm部署django項目到云服務(wù)器的詳細(xì)流程,首先大家需要先下載python3.8壓縮包,然后通過一系列命令完成操作,具體實現(xiàn)方法,跟隨小編一起看看吧2021-06-06Python偏函數(shù)Partial function使用方法實例詳解
這篇文章主要介紹了Python偏函數(shù)Partial function使用方法實例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06Python實現(xiàn)解析命令行參數(shù)的常見方法總結(jié)
除ide的執(zhí)行方式外,命令行的方式執(zhí)行Python腳本是參數(shù)化程序執(zhí)行的一種常見且簡單的方法。本文總結(jié)了三個常見的獲取和解析命令行參數(shù)的方法,需要的可以參考一下2022-10-10Python畫柱狀統(tǒng)計圖操作示例【基于matplotlib庫】
這篇文章主要介紹了Python畫柱狀統(tǒng)計圖操作,結(jié)合實例形式分析了Python基于matplotlib庫實現(xiàn)圖形繪制的相關(guān)操作技巧,需要的朋友可以參考下2018-07-07Python機(jī)器學(xué)習(xí)之隨機(jī)梯度下降法的實現(xiàn)
如果當(dāng)我們數(shù)據(jù)量和樣本量非常大時,每一項都要參與到梯度下降,那么它的計算量時非常大的,所以我們需要采用隨機(jī)梯度下降法。本文介紹了Python實現(xiàn)隨機(jī)梯度下降法的方法,希望對大家有所幫助2023-02-02