Python MySQLdb 學習總結(轉)

轉自http://www.cnblogs.com/coser/archive/2012/01/12/2320741.html 感謝@糖拌鹹魚html

 

任何應用都離不開數據,因此在學習python的時候,固然也要學習一個如何用python操做數據庫了。MySQLdb就是python對mysql數據庫操做的模塊。官方Introduction : MySQLdb is an thread-compatible interface to the popular MySQL database server that provides the Python database API. 它其實至關於翻譯了對應C的接口。python

   使用這種數據庫接口大可能是就是執行鏈接數據庫->執行query->提取數據->關閉鏈接 這幾個步驟。MySQLdb提供比較關鍵的對象,分別是Connection、Cursor、Result。具體使用步驟很簡單先不寫了,先寫一些我的認爲比較重要、值得注意的地方。mysql

 一、雖然在MySQLdb.Connect(host ,user , passw , db)函數中,咱們常用的只是這幾個參數,可是其實裏面還有不少好比字符集、線程安全、ssl等也都是很重要的參數,使用時要身份注意。sql

 二、當使用Connection.query()函數進行query後,connection 對象能夠返回兩種result,分別是store_result和use_result,store_result 將結果集存回client端,而use_result則是結果集保存在server端,而且維護了一個鏈接,會佔用server資源。此時,不能夠進行任何其餘的查詢。建議使用store_result,除非返回結果集(result set)過大或是沒法使用limit的情形。數據庫

 三、提取(fetch)數據的返回形式大多有三種情形。 as a tuple(how=0) ;as dictionaries, key=column or table.column if duplicated(how=1);as dictionaries, key=table.column (how=2)安全

 四、每次fetch,在result內部都會產生數據位置的移動,也就是說假若有10行數據,執行result.fetch_row(3,0),會獲得前三行,再執行result.fetch_row(3,0),則會獲得中間的三行,因此說fetch會致使position的移動。另外值得注意的是,若是使用use_result,也就是數據存儲在server時,在fetch全部的條目以前,不能進行任何的query操做。網絡

 五、mysql自己不支持遊標(Cursor),可是MySQLdb對Cursor進行了仿真。重要的執行query方法有execute 和 executemany 。execute方法,執行單條sql語句,調用executemany方法很好用,數據庫性能瓶頸很大一部分就在於網絡IO和磁盤IO將多個insert放在一塊兒,只執行一次IO,能夠有效的提高數據庫性能。遊標cursor具備fetchone、fetchmany、fetchall三個方法提取數據,每一個方法都會致使遊標遊動,因此必須關注遊標的位置。遊標的scroll(value, mode)方法可使得遊標進行卷動,mode參數指定相對當前位置(relative)仍是以絕對位置(absolute)進行移動。dom

 六、MySQLdb提供了不少函數方法,在官方指南里沒有徹底羅列,使用者能夠用help去看看,裏面提供了不少方便的東西。ide

 七、對於mysql來講,若是使用支持事務的存儲引擎,那麼每次操做後,commit是必須的,不然不會真正寫入數據庫,對應rollback能夠進行相應的回滾,可是commit後是沒法再rollback的。commit() 能夠在執行不少sql指令後再一次調用,這樣能夠適當提高性能。函數

 八、executemany處理過多的命令也不見得必定好,由於數據一塊兒傳入到server端,可能會形成server端的buffer溢出,而一次數據量過大,也有可能產生一些意想不到的麻煩。合理,分批次executemany是個不錯的辦法。

  最後,我本身寫了個pyMysql模塊,主要是對MySQLdb提供的經常使用方法進行了簡單的再次封裝,也藉此機會好好學習下MySQLdb,以及練習python的編碼。該程序使用的數據庫表,採用myisam引擎,因此沒加上commit(),通常最好仍是要加上的。

 

測試輸出:

 ******************** lines: 5 ********************

ID : 1 , Author_last : Greene , Author_First : Graham , Country : United Kingdom
ID : 4 , Author_last : Peter , Author_First : David , Country : China
ID : 5 , Author_last : mayday , Author_First : Feng , Country : France
ID : 6 , Author_last : zhang , Author_First : lixin , Country : France
ID : 9 , Author_last : zhang111 , Author_First : lixin , Country : France
******************** 3 行被插入 ********************
******************** lines: 8 ********************
-----------
country : United Kingdom
author_id : 1
author_first : Graham
author_last : Greene
-----------
country : China
author_id : 4
author_first : David
author_last : Peter
-----------
country : France
author_id : 5
author_first : Feng
author_last : mayday
-----------
country : France
author_id : 6
author_first : lixin
author_last : zhang
-----------
country : France
author_id : 9
author_first : lixin
author_last : zhang111
-----------
country : cccccc
author_id : 53
author_first : bbbbbb
author_last : aaaaaa
-----------
country : ffffff
author_id : 54
author_first : eeeeee
author_last : dddddd
-----------
country : iiiiii
author_id : 55
author_first : hhhhhh
author_last : gggggg

 

  1 #-*- encoding:gb2312 -*-_
  2 '''
  3 Created on 2012-1-12
  4 @author: xiaojay
  5 '''
  6 import MySQLdb
  7 import MySQLdb.cursors
  8  
  9 STORE_RESULT_MODE = 0
 10 USE_RESULT_MODE = 1
 11  
 12 CURSOR_MODE = 0
 13 DICTCURSOR_MODE = 1
 14 SSCURSOR_MODE = 2
 15 SSDICTCURSOR_MODE = 3
 16  
 17 FETCH_ONE = 0
 18 FETCH_MANY = 1
 19 FETCH_ALL = 2
 20  
 21 class PyMysql:
 22     def __init__(self):
 23         self.conn = None
 24         pass
 25     def newConnection(self,host,user,passwd,defaultdb):
 26         """
 27         創建一個新鏈接,指定host、用戶名、密碼、默認數據庫
 28         """
 29         self.conn = MySQLdb.Connect(host,user,passwd,defaultdb)
 30         if self.conn.open == False:
 31             raise None
 32     def closeConnnection(self):
 33         """
 34         關閉當前鏈接
 35         """
 36         self.conn.close()
 37      
 38     def query(self,sqltext,mode=STORE_RESULT_MODE):
 39         """
 40         做用:使用connection對象的query方法,並返回一個元組(影響行數(int),結果集(result))
 41         參數:sqltext:sql語句
 42              mode=STORE_RESULT_MODE(0) 表示返回store_result,mode=USESTORE_RESULT_MODE(1) 表示返回use_result
 43         返回:元組(影響行數(int),結果集(result)
 44         """
 45         if self.conn==None or self.conn.open==False :
 46             return -1
 47         self.conn.query(sqltext)
 48         if mode == 0 :
 49             result = self.conn.store_result() 
 50         elif mode == 1 :
 51             result = self.conn.use_result()
 52         else :
 53             raise Exception("mode value is wrong.")
 54         return (self.conn.affected_rows(),result)
 55      
 56     def fetch_queryresult(self,result,maxrows=1,how=0,moreinfo=False):
 57         """
 58         參數:result: query後的結果集合
 59             maxrows: 返回的最大行數
 60             how: 以何種方式存儲結果
 61              (0:tuple,1:dictionaries with columnname,2:dictionaries with table.columnname)
 62             moreinfo 表示是否獲取更多額外信息(num_fields,num_rows,num_fields)
 63         返回:元組(數據集,附加信息(當moreinfo=False)或單一數據集(當moreinfo=True)
 64         """
 65         if result == None : return None
 66         dataset =  result.fetch_row(maxrows,how)
 67         if moreinfo is False :
 68             return dataset
 69         else :
 70             num_fields = result.num_fields()
 71             num_rows = result.num_rows()
 72             field_flags = result.field_flags()
 73             info = (num_fields,num_rows,field_flags)
 74             return (dataset,info)
 75          
 76     def execute(self,sqltext,args=None,mode=CURSOR_MODE,many=False):
 77         """
 78         做用:使用遊標(cursor)的execute 執行query
 79         參數:sqltext: 表示sql語句
 80              args: sqltext的參數
 81              mode:以何種方式返回數據集
 82                 CURSOR_MODE = 0 :store_result , tuple
 83                 DICTCURSOR_MODE = 1 : store_result , dict
 84                 SSCURSOR_MODE = 2 : use_result , tuple
 85                 SSDICTCURSOR_MODE = 3 : use_result , dict 
 86              many:是否執行多行操做(executemany)
 87         返回:元組(影響行數(int),遊標(Cursor))
 88         """
 89         if mode == CURSOR_MODE :
 90             curclass = MySQLdb.cursors.Cursor
 91         elif mode == DICTCURSOR_MODE :
 92             curclass = MySQLdb.cursors.DictCursor
 93         elif mode == SSCURSOR_MODE :
 94             curclass = MySQLdb.cursors.SSCursor
 95         elif mode == SSDICTCURSOR_MODE :
 96             curclass = MySQLdb.cursors.SSDictCursor
 97         else :
 98             raise Exception("mode value is wrong")
 99          
100         cur = self.conn.cursor(cursorclass=curclass)
101         line = 0
102         if many == False :
103             if args == None : 
104                 line = cur.execute(sqltext)
105             else :
106                 line = cur.execute(sqltext,args)
107         else :
108             if args == None :
109                 line = cur.executemany(sqltext)
110             else :
111                 line = cur.executemany(sqltext,args)
112         return (line , cur )
113      
114     def fetch_executeresult(self,cursor,mode=FETCH_ONE,rows=1):
115         """
116         做用:提取cursor獲取的數據集
117         參數:cursor:遊標
118              mode:執行提取模式
119               FETCH_ONE: 提取一個; FETCH_MANY :提取rows個 ;FETCH_ALL : 提取全部
120              rows:提取行數
121         返回:fetch數據集
122         """
123         if cursor == None : 
124             return
125         if mode == FETCH_ONE :
126             return cursor.fetchone()
127         elif mode == FETCH_MANY :
128             return cursor.fetchmany(rows)
129         elif mode == FETCH_ALL :
130             return cursor.fetchall()
131          
132 if __name__=="__main__" :
133     print help (PyMysql)
View Code
#-*- encoding:gb2312 -*-
import PyMysql
 
"""
authors 這張表很簡單。
+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| author_id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| author_last  | varchar(50) | YES  |     | NULL    |                |
| author_first | varchar(50) | YES  | MUL | NULL    |                |
| country      | varchar(50) | YES  |     | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+
本文主要的全部操做都針對該表。
"""
 
def printAuthors(res,mode=0,lines=0):
    """
    格式化輸出
    """
    print "*"*20, " lines: ",lines ," ","*"*20
    if mode==0  :
        for author_id , author_last , author_first , country in res :
            print "ID : %s , Author_last : %s , Author_First : %s , Country : %s" \
            % (author_id , author_last , author_first , country )
    else :
        for item in res :
            print "-----------"               
            for key in item.keys():
                print key ," : ",item[key]
 
#創建鏈接
mysql = PyMysql.PyMysql()
mysql.newConnection(
        host="localhost", 
        user="root", 
        passwd="peterbbs", 
        defaultdb="bookstore")
""
#定義sql語句
sqltext = "select * from authors order by author_id "
#調用query方法,獲得result
lines , res = mysql.query(sqltext, mode=PyMysql.STORE_RESULT_MODE)
#提取數據
data = mysql.fetch_queryresult(res, maxrows=20, how=0, moreinfo=False)
#打印
printAuthors(data,0,lines)
 
#演示多行插入
sqltext = "insert into authors (author_last,author_first,country) values (%s,%s,%s)"
args = [('aaaaaa','bbbbbb','cccccc'),('dddddd','eeeeee','ffffff'),('gggggg','hhhhhh','iiiiii')]
lines ,cur = mysql.execute(sqltext,args,mode=PyMysql.DICTCURSOR_MODE,many=True)
print "*"*20, lines ,"行被插入 ","*"*20
 
sqltext = "select * from authors order by author_id "
#調用cursor.execute方法,獲得result
lines ,cur = mysql.execute(sqltext,mode=PyMysql.DICTCURSOR_MODE)
#提取數據
data = mysql.fetch_executeresult(cur, mode=PyMysql.FETCH_MANY, rows=20)
#打印
printAuthors(data,1,lines)
 
#關閉鏈接
mysql.closeConnnection()
測試代碼
相關文章
相關標籤/搜索