在開發(fā)的過程中避免不了和數(shù)據(jù)庫的交互,在實(shí)際環(huán)境中用的最多的 Mysql 數(shù)據(jù)庫,那 python 是怎么和 Mysql 進(jìn)行交互的呢,python 使用一個(gè)叫 MySQLdb 的庫來連接 MySQL,好的,下面最要從 MySQLdb 的安裝、連接 MySQL、執(zhí)行 sql 語句、如何取得結(jié)果、關(guān)閉數(shù)據(jù)庫連接來講述一下:
我使用的是 ubuntu 系統(tǒng),安裝方法為:apt-get install python-MySQLdb,這樣當(dāng)在 python 環(huán)境執(zhí)行 import MySQLdb 不報(bào)錯就是安
root@ubuntu:~# python
Python 2.7.4 (default, Apr 19 2013, 18:32:33)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import MySQLdb
>>>
MySQLdb 提供的 connect 方法用來和數(shù)據(jù)庫建立連接,接收數(shù)個(gè)參數(shù),返回連接對象,如:
conn=MySQLdb.connect(host="localhost",user="root",passwd="sa",db="mytable",port=3306)
比較常用的參數(shù)包括:
host:數(shù)據(jù)庫主機(jī)名.默認(rèn)是用本地主機(jī).
user:數(shù)據(jù)庫登陸名.默認(rèn)是當(dāng)前用戶.
passwd:數(shù)據(jù)庫登陸的秘密.默認(rèn)為空.
db:要使用的數(shù)據(jù)庫名.沒有默認(rèn)值,如果在這里設(shè)置了 db,則連接時(shí)直接連接到 Mysql 的 db 設(shè)置的數(shù)據(jù)庫中
port:MySQL服務(wù)使用的TCP端口.默認(rèn)是3306.
注:connect 中的 host、user、passwd 等可以不寫,只有在寫的時(shí)候按照 host、user、passwd、db(可以不寫)、port 順序?qū)懢涂梢?,注意端口?port=3306 還是不要省略的為好,如果沒有 db 在 port 前面,直接寫 3306 會報(bào)錯
連接成功后,如需切換該用戶的其他數(shù)據(jù)庫,使用以下語句:conn.select_db('mysql')形式切換數(shù)據(jù)庫
>>> 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 行:連接數(shù)據(jù)庫
第 2 行:選擇連接 mysql 這個(gè)數(shù)據(jù)庫
第 3 行以下是獲取數(shù)據(jù)庫表,語法后面會講
因該模塊底層其實(shí)是調(diào)用 C API 的,所以,需要先得到當(dāng)前指向數(shù)據(jù)庫的指針
>>> cur=con.cursor()
我們利用 cursor 提供的方法來進(jìn)行操作,方法主要是 1.執(zhí)行命令 2.接收結(jié)果
ursor 用來執(zhí)行命令的方法:
execute(query, args):執(zhí)行單條 sql 語句,接收的參數(shù)為 sql 語句本身和使用的參數(shù)列表,返回值為受影響的行數(shù)
executemany(query, args):執(zhí)行單挑 sql 語句,但是重復(fù)執(zhí)行參數(shù)列表里的參數(shù),返回值為受影響的行數(shù)
cursor 用來接收返回值的方法:
fetchall(self):接收全部的返回結(jié)果行.
fetchmany(size=None):接收 size 條返回結(jié)果行.如果 size 的值大于返回的結(jié)果行的數(shù)量,則會返回 cursor.arraysize 條數(shù)據(jù).
fetchone():返回一條結(jié)果行.
scroll(value, mode='relative'):移動指針到某一行.如果 mode='relative',則表示從當(dāng)前所在行移動 value 條,如果 mode='absolute',則表示從結(jié)果集的第一行移動 value 條.
先來看一下 execute 的增刪改查的操作
#創(chuàng)建數(shù)據(jù)庫 51ctotest
>>> cur.execute('create database 51ctotest')
#選擇數(shù)據(jù)庫 51ctotest
>>>con.select_db('51ctotest')
#創(chuàng)建表 51cto,id 自增
>>>cur.execute('create table if not exists 51cto(id int(11) PRIMARY KEY AUTO_INCREMENT,name varchar(20),age int(3))')
#插入一行數(shù)據(jù),只給 name、age 賦值,讓 id 自增
#使用 sql 語句,這里要接收的參數(shù)都用 %s 占位符.要注意的是,無論你要插入的數(shù)據(jù)是什 # 么類型,占位符永遠(yuǎn)都要用 %s,后面的數(shù)值為元組或者列表
>>>cur.execute("insert into 51cto(name,age) values(%s,%s)",('fan',25))
#插入多行數(shù)據(jù),用 executemany,它會循環(huán)插入后面元組中的所有值
>>> cur.executemany("insert into 51cto(name,age) values(%s,%s)",(('te',25),('fei',26),('musha',25)))
3L
#查詢
>>> cur.execute('select * from 51cto')
5L
#我們使用了 fetchall 這個(gè)方法.這樣,cds 里保存的將會是查詢返回的全部結(jié)果.每條結(jié)果都是一個(gè) tuple 類型的數(shù)據(jù),這些 tuple 組成了一個(gè) tuple
>>> cur.fetchall()
((1L, 'fan', 25L), (2L, 'fan', 25L), (3L, 'te', 25L), (4L, 'fei', 26L), (5L, 'musha', 25L))
#再次查詢,會看到查詢不到結(jié)果,因?yàn)闊o論 fetchone、fetchall、fetchmany 指針是會發(fā)生移動的。所以,若不重置指針,那么使用 fetchall 的信息將只會包含指針后面的行內(nèi)容。使用 fetchall 把指針挪到了最后,可以用 scroll 手動把指針挪到一個(gè)位置
>>> 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)
這里參數(shù)含義為:
int:移動的行數(shù),整數(shù);在相對模式下,正數(shù)向下移動,負(fù)值表示向上移動。
parm:移動的模式,默認(rèn) 是 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,要做到這點(diǎn)也很簡單,那就是建立數(shù)據(jù)庫連接是傳遞 cusorclass 參數(shù),或者在獲取 Cursor 對象時(shí)傳遞 cusorclass 參數(shù)即可
>>> 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'}
#更新,習(xí)慣 %s 的用法
>>> cur.execute('update 51cto set name=%s where id=3',('Mus'))
>>> cur.scroll(2,'absolute')
>>> cur.fetchone()
{'age': 25L, 'id': 3L, 'name': 'Mus'}
#在執(zhí)行完插入或刪除或修改操作后,需要調(diào)用一下 conn.commit() 方法進(jìn)行提交.這樣,數(shù)據(jù)才會真正保 存在數(shù)據(jù)庫中
>>> con.commit()
#最后關(guān)閉游標(biāo),關(guān)閉連接
>>> cur.close()
>>> con.close()