13 python 之 MySQLdb 庫的使用

在開發的過程中避免不了和數據庫的交互,在實際環境中用的最多的 Mysql 數據庫,那 python 是怎麼和 Mysql 進行交互的呢,python 使用一個叫 MySQLdb 的庫來連接 MySQL,好的,下面最要從 MySQLdb 的安裝、連接 MySQL、執行 sql 語句、如何取得結果、關閉數據庫連接來講述一下:

  1. MySQLdb 的安裝

我使用的是 ubuntu 系統,安裝方法為:apt-get install python-MySQLdb,這樣當在 python 環境執行 import MySQLdb 不報錯就是安

root@ubuntu:~# pythonPython 2.7.4 (default, Apr 19 2013, 18:32:33)[GCC 4.7.3] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import MySQLdb>>>  
  1. 如何連接 Mysql

MySQLdb 提供的 connect 方法用來和數據庫建立連接,接收數個參數,返回連接對象,如:

conn=MySQLdb.connect(host="localhost",user="root",passwd="sa",db="mytable",port=3306)  

比較常用的參數包括:

host:數據庫主機名.默認是用本地主機.
user:數據庫登陸名.默認是當前用戶.
passwd:數據庫登陸的秘密.默認為空.
db:要使用的數據庫名.沒有默認值,如果在這裡設置了 db,則連接時直接連接到 Mysql 的 db 設置的數據庫中
port:MySQL服務使用的TCP端口.默認是3306.

註:connect 中的 host、user、passwd 等可以不寫,只有在寫的時候按照 host、user、passwd、db(可以不寫)、port 順序寫就可以,注意端口號 port=3306 還是不要省略的為好,如果沒有 db 在 port 前面,直接寫 3306 會報錯

連接成功後,如需切換該用戶的其他數據庫,使用以下語句:conn.select_db(\'mysql\')形式切換數據庫

>>> con=MySQLdb.connect(\'localhost\',\'root\',\'123456\',port=3306)>>> con.select_db(\'mysql\')>>> cur=con.cursor>>> cur.execute(\'show tables\')24L>>> cur.fetchall((\'columns_priv\',), (\'db\',), (\'event\',), (\'func\',), (\'general_log\',), (\'help_category\',), (\'help_keyword\',), (\'help_relation\',), (\'help_topic\',), (\'host\',), (\'ndb_binlog_index\',), (\'plugin\',), (\'proc\',), (\'procs_priv\',), (\'proxies_priv\',), (\'servers\',), (\'slow_log\',), (\'tables_priv\',), (\'time_zone\',), (\'time_zone_leap_second\',), (\'time_zone_name\',), (\'time_zone_transition\',), (\'time_zone_transition_type\',), (\'user\',))  

第 1 行:連接數據庫
第 2 行:選擇連接 mysql 這個數據庫
第 3 行以下是獲取數據庫表,語法後面會講

  1. 怎麼操作數據庫,MySQLdb 用游標(指針)cursor 的方式操作數據庫

因該模塊底層其實是調用 C API 的,所以,需要先得到當前指向數據庫的指針

>>> cur=con.cursor  
  1. 數據庫的操作和結果顯示

我們利用 cursor 提供的方法來進行操作,方法主要是 1.執行命令 2.接收結果

ursor 用來執行命令的方法:
execute(query, args):執行單條 sql 語句,接收的參數為 sql 語句本身和使用的參數列表,返回值為受影響的行數
executemany(query, args):執行單挑 sql 語句,但是重複執行參數列表裡的參數,返回值為受影響的行數

cursor 用來接收返回值的方法:
fetchall(self):接收全部的返回結果行.
fetchmany(size=None):接收 size 條返回結果行.如果 size 的值大於返回的結果行的數量,則會返回 cursor.arraysize 條數據.
fetchone:返回一條結果行.
scroll(value, mode=\'relative\'):移動指針到某一行.如果 mode=\'relative\',則表示從當前所在行移動 value 條,如果 mode=\'absolute\',則表示從結果集的第一行移動 value 條.

先來看一下 execute 的增刪改查的操作

 #創建數據庫 51ctotest>>> cur.execute(\'create database 51ctotest\') #選擇數據庫 51ctotest>>>con.select_db(\'51ctotest\') #創建表 51cto,id 自增>>>cur.execute(\'create table if not exists 51cto(id int(11) PRIMARY KEY AUTO_INCREMENT,name varchar(20),age int(3))\') #插入一行數據,只給 name、age 賦值,讓 id 自增 #使用 sql 語句,這裡要接收的參數都用 %s 佔位符.要注意的是,無論你要插入的數據是什 # 麼類型,佔位符永遠都要用 %s,後面的數值為元組或者列表>>>cur.execute("insert into 51cto(name,age) values(%s,%s)",(\'fan\',25)) #插入多行數據,用 executemany,它會循環插入後面元組中的所有值>>> cur.executemany("insert into 51cto(name,age) values(%s,%s)",((\'te\',25),(\'fei\',26),(\'musha\',25)))3L #查詢>>> cur.execute(\'select * from 51cto\')5L #我們使用了 fetchall 這個方法.這樣,cds 裡保存的將會是查詢返回的全部結果.每條結果都是一個 tuple 類型的數據,這些 tuple 組成了一個 tuple>>> cur.fetchall((1L, \'fan\', 25L), (2L, \'fan\', 25L), (3L, \'te\', 25L), (4L, \'fei\', 26L), (5L, \'musha\', 25L)) #再次查詢,會看到查詢不到結果,因為無論 fetchone、fetchall、fetchmany 指針是會發生移動的。所以,若不重置指針,那麼使用 fetchall 的信息將只會包含指針後面的行內容。使用 fetchall 把指針挪到了最後,可以用 scroll 手動把指針挪到一個位置>>> cur.fetchall      >>> cur.scroll(1,\'absolute\')>>> for i in cur.fetchall:...     print i ...(2L, \'fan\', 25L)(3L, \'te\', 25L)(4L, \'fei\', 26L)(5L, \'musha\', 25L) 

這裡有必要說一下 scroll:

cur.scroll(int,parm)  

這裡參數含義為:

int:移動的行數,整數;在相對模式下,正數向下移動,負值表示向上移動。
parm:移動的模式,默認 是 relative,相對模式;可接受 absoulte,絕對模式。

 #fetchone一次只取一行,指針下移  fetchmany(size)一次去 size 行>>> cur.scroll(1,\'absolute\')>>> cur.fetchone(2L, \'fan\', 25L)>>> cur.fetchmany(2)((3L, \'te\', 25L), (4L, \'fei\', 26L)) #普通取出是元組的形式,再從裡面取值不好取,那怎麼取成字典的格式呢,MySQLdb 中有 DictCursor,要做到這點也很簡單,那就是建立數據庫連接是傳遞 cusorclass 參數,或者在獲取 Cursor 對像時傳遞 cusorclass 參數即可>>> cur = con.cursor(cursorclass=MySQLdb.cursors.DictCursor) >>> cur.execute(\'select * from 51cto\')5L>>> for i in cur.fetchall:...     print i...{\'age\': 25L, \'id\': 2L, \'name\': \'fan\'}{\'age\': 25L, \'id\': 3L, \'name\': \'te\'}{\'age\': 26L, \'id\': 4L, \'name\': \'fei\'}{\'age\': 25L, \'id\': 5L, \'name\': \'musha\'} #更新,習慣 %s 的用法>>> cur.execute(\'update 51cto set name=%s where id=3\',(\'Mus\'))>>> cur.scroll(2,\'absolute\')>>> cur.fetchone       {\'age\': 25L, \'id\': 3L, \'name\': \'Mus\'} #在執行完插入或刪除或修改操作後,需要調用一下 conn.commit 方法進行提交.這樣,數據才會真正保 存在數據庫中>>> con.commit #最後關閉游標,關閉連接>>> cur.close>>> con.close  
《Python實戰-從菜鳥到大牛的進階之路》