python网络编程库_python网络编程学习笔记(9):数据库客户端
一、DB-API概述
python支持很多不同的數(shù)據(jù)庫。由于不同的賣家服務器導致和數(shù)據(jù)庫通信的網(wǎng)絡協(xié)議各有不同。在python的早期版本中,每一種數(shù)據(jù)庫都帶有自己的python模塊,所有這些模塊以不同的方式工作,并提供不同的函數(shù)。這種方法不便于編寫能夠在多種數(shù)據(jù)庫服務器類型中運行的代碼,于是DB-API庫函數(shù)產(chǎn)生。在DB-API中,所有連接數(shù)據(jù)庫的模塊即便是底層網(wǎng)絡協(xié)議不同,也會提供一個共同的接口。這一點和JAVA中的JDBC和ODBC類似。
DB-API下載地址:http://wiki.python.org/moin/DatabaseProgramming,目前版本是2.0,支持數(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/。(關于PostgreSQL的安裝等更加詳細的介紹,可以見http://wenku.baidu.com/view/8e32d10c6c85ec3a87c2c500.html。)連接PostgreSQL數(shù)據(jù)庫:
importpsycopg2print "connecting to test"##test為數(shù)據(jù)庫名
dbh=psycopg2.connect('dbname=test user=postgres')print "connection successful"
2、MySQL
對于MySQL,python的接口是已知的MySQLdb或者MySQL-Python,下載地址:http://sourceforge.net/projects/mysql-python/。與PostgreSQL不同的是,MySQLdb connect()函數(shù)可以帶各種參數(shù),具體如下:
參數(shù)
說明
user
用戶名,默認為當前登錄用戶。
passwd
用戶密碼,沒有默認的。
db
連接的數(shù)據(jù)庫名。
host
數(shù)據(jù)庫主機名。
port
TCP端口,默認是3306。
舉例,連接test數(shù)據(jù)庫:
importMySQLdbprint "connecting..."dbh=MySQLdb.connect(db="test")print "connection successful."dbh.close()
三、簡單操作(以PostgreSQL為例)
這里以PostgreSQL為例介紹創(chuàng)建表、查詢表等操作。例子中數(shù)據(jù)庫名為test,用戶名為postgres,輸入一個表名,向表中插入數(shù)據(jù)并進行查詢。具體如下,已進行了注示:
importpsycopg2print "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=1
c='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 inrows:printrow
dbh.commit()#以上對數(shù)據(jù)庫的操作事務生效
dbh.close()
1、事務
多數(shù)數(shù)據(jù)庫支持事務,事務可以將多條對數(shù)據(jù)庫的改動放在一條命令中。在上面的例子中,當未曾執(zhí)行commit()命令時,以上對數(shù)據(jù)庫的操作均不會生效。另外還有一個函數(shù)rollback(),這個函數(shù)可以有效的放棄上一次執(zhí)行commit()或者rollback()之后的改動。這個函數(shù)在發(fā)現(xiàn)錯誤,并想放棄已經(jīng)發(fā)出的事務時,非常有效。對于不支持事務的數(shù)據(jù)庫,改變會立刻執(zhí)行,commit()什么也不做,但rollback()會報錯。
2、效率
執(zhí)行事件的性能很大程序上取決于不同的服務器,一般來說,在每個單獨的命令后都提交是更新數(shù)據(jù)庫最慢的方法,但如果一次提交很大數(shù)據(jù)又會使服務器產(chǎn)生buffer溢出。因此,應該合理處理提交的數(shù)量。
四、參數(shù)風格
在上面的例子中,使用了printf()一樣的類型格式。但實際上,在DB-API中,不同的數(shù)據(jù)庫所支持的參數(shù)風絡不同,必須選擇合適的方法,否則程序不會執(zhí)行。下面的方法,可以知道當前所支持的類型格式。
>>> importpsycopg2>>> printpsycopg2.paramstyle
pyformat
這一結(jié)果可以看出,當前支持pyformat格式。
針對DB-API說明書,以使用頻度由小變大的順序介紹:
qmark
表示question-mark風格。指令字符串中的數(shù)據(jù)的每一位都被用一個問號替換,參數(shù)以list或tuple的形式給出。例如:INSERT INTO ch14 VALUES (?, ?)。
format
使用和printf()一樣的類型格式,不支持對于指定參數(shù)Python的擴展名。它帶一個list或tuple來轉(zhuǎn)換。例如:INSERT INTO ch14 VALUES(%d, %s)
numeric
表示numeric風格。指令字符串中的數(shù)據(jù)的每一位都被一個后面是數(shù)字的冒號替換(數(shù)字以1開始),參數(shù)以list或tuple的形式給出。例如:INSERT INTO ch14 VALUES(:1, :2)
named
表示named風格。和numeric類似,但是在冒號后面用名稱取代數(shù)字。帶一個dictionary用來轉(zhuǎn)換。例如:INSERT INTO ch14 VALUES(:number, :text)
pyformat
支持Python風格的參數(shù),帶dictionary用來轉(zhuǎn)換。例如:INSERT INTO ch14 VALUES(%(number)d, %(text)s)。
五、重復指令
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ù)帶一個指令和一列指令運行的記錄。列表上的每條記錄要么是一個list,要么是一個dictionary。
importpsycopg2print "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()主要的缺點是,在需要執(zhí)行指令前把所有的記錄放在內(nèi)存中。如果數(shù)據(jù)大的話,這就是一個問題,它會占有系統(tǒng)的所有內(nèi)存資源。如果executemany()不能滿足需要,那么除了execute()之外,還是有可能取得性能優(yōu)化的。根據(jù)DB-API說明,當execute()被周期性調(diào)用時,數(shù)據(jù)庫后端可以執(zhí)行優(yōu)化。但是它的第一個參數(shù)必須指向同一個對象,而不是一個含有相同值的字符串,即在內(nèi)存中的同一個字符串對象。和executemany()一樣,這樣并不能保證優(yōu)化,并且也不能期望execute()運行得比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",它是“關于數(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)
importpsycopg2print "connecting to bbstime"dbh=psycopg2.connect('dbname=bbstime user=postgres')print "connection successful"cur=dbh.cursor()
cur.execute("SELECT * FROM asd")for column incur.description:printcolumn
dbh.close()
八、計算行數(shù)
方法有兩種,一種是用len(),一種是用rowcount。
importpsycopg2print "connecting to bbstime"dbh=psycopg2.connect('dbname=bbstime user=postgres')print "connection successful"cur=dbh.cursor()
cur.execute("SELECT * FROM test")
rows=cur.fetchall()printlen(rows)#利用len來計算行數(shù)print "rows:",cur.rowcount#利用rowcount來計算行數(shù)
dbh.close()
總結(jié)
以上是生活随笔為你收集整理的python网络编程库_python网络编程学习笔记(9):数据库客户端的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: easyui的tree获取父节点_力扣
- 下一篇: python coding_Python