溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python操作數(shù)據(jù)庫(kù)之 MySQL

發(fā)布時(shí)間:2020-08-04 06:01:20 來(lái)源:網(wǎng)絡(luò) 閱讀:1055 作者:四京 欄目:MySQL數(shù)據(jù)庫(kù)

Python操作數(shù)據(jù)庫(kù)之MySQL

 

 

 

一、安裝Python-MySQLdb模塊

Python-MySQLdb是一個(gè)操作數(shù)據(jù)庫(kù)的模塊,Python 通過(guò)它對(duì) mysql 數(shù)據(jù)實(shí)現(xiàn)各種操作。

如果要源碼安裝,可以這里下載: https://pypi.Python.org/pypi/MySQL-Python/

解壓安裝包,進(jìn)入解壓目錄執(zhí)行以下命令安裝

python setup.py install

 

ubuntu 下可以這么做:

sudo apt-get install build-essential Python-dev libmysqlclient-dev
sudo apt-get install Python-MySQLdb

 

 

pip安裝:

pip install mysql-Python

 

安裝之后,在 python 交互模式下:

>>> import MySQLdb

如果不報(bào)錯(cuò),恭喜你,已經(jīng)安裝好了。

 

 

二、操作數(shù)據(jù)庫(kù)

操作數(shù)據(jù)庫(kù)流程:

1、導(dǎo)入MySQLdb模塊

2、創(chuàng)建數(shù)據(jù)庫(kù)連接

3、執(zhí)行SQL語(yǔ)句和存儲(chǔ)過(guò)程

4、關(guān)閉數(shù)據(jù)庫(kù)連接

 

 

創(chuàng)建MySQL連接對(duì)象

>>> import MySQLdb
>>> conn = MySQLdb.connect(host="localhost",user="root",passwd="123456",db="python",port=3306,charset="utf8")
>>>

 

命令含義解釋:

host:等號(hào)的后面應(yīng)該填寫(xiě) mysql 數(shù)據(jù)庫(kù)的地址,因?yàn)榫蛿?shù)據(jù)庫(kù)就在本機(jī)上(也稱作本地),所以使用 localhost,注意引號(hào)。如果在其它的服務(wù)器上,這里應(yīng)該填寫(xiě) ip 地址。一般中小型的網(wǎng)站,數(shù)據(jù)庫(kù)和程序都是在同一臺(tái)服務(wù)器(計(jì)算機(jī))上,就使用 localhost 了。

user:登錄數(shù)據(jù)庫(kù)的用戶名,這里一般填寫(xiě)"root",還是要注意引號(hào)。當(dāng)然,如果讀者命名了別的用戶名,數(shù)據(jù)庫(kù)管理者提供了專有用戶名,就更改為相應(yīng)用戶。但是,不同用戶的權(quán)限可能不同,所以,在程序中,如果要操作數(shù)據(jù)庫(kù),還要注意所擁有的權(quán)限。在這里用 root,就放心了,什么權(quán)限都有啦。不過(guò),這樣做,在大型系統(tǒng)中是應(yīng)該避免的。

passwd:上述 user 賬戶對(duì)應(yīng)的登錄 mysql 的密碼。我在上面的例子中用的密碼是"123123"。不要忘記引號(hào)。

db:就是剛剛通 create 命令建立的數(shù)據(jù)庫(kù),我建立的數(shù)據(jù)庫(kù)名字是"qiwsirtest",還是要注意引號(hào)??垂偃绻⒌臄?shù)據(jù)庫(kù)名字不是這個(gè),就寫(xiě)自己所建數(shù)據(jù)庫(kù)名字。

port:一般情況,mysql 的默認(rèn)端口是 3306,當(dāng) mysql 被安裝到服務(wù)器之后,為了能夠允許網(wǎng)絡(luò)訪問(wèn),服務(wù)器(計(jì)算機(jī))要提供一個(gè)訪問(wèn)端口給它。

charset:這個(gè)設(shè)置,在很多教程中都不寫(xiě),結(jié)果在真正進(jìn)行數(shù)據(jù)存儲(chǔ)的時(shí)候,發(fā)現(xiàn)有亂碼。這里我將 qiwsirtest 這個(gè)數(shù)據(jù)庫(kù)的編碼設(shè)置為 utf-8 格式,這樣就允許存入漢字而無(wú)亂碼了。注意,在 mysql 設(shè)置中,utf-8 寫(xiě)成 utf8,沒(méi)有中間的橫線。但是在 Python 文件開(kāi)頭和其它地方設(shè)置編碼格式的時(shí)候,要寫(xiě)成 utf-8。切記!

 

 

Python 建立了與數(shù)據(jù)的連接,其實(shí)是建立了一個(gè) MySQLdb.connect() 的實(shí)例對(duì)象,或者泛泛地稱之為連接對(duì)象,Python 就是通過(guò)連接對(duì)象和數(shù)據(jù)庫(kù)對(duì)話。這個(gè)對(duì)象常用的方法有:

 

commit():如果數(shù)據(jù)庫(kù)表進(jìn)行了修改,提交保存當(dāng)前的數(shù)據(jù)。當(dāng)然,如果此用戶沒(méi)有權(quán)限就作罷了,什么也不會(huì)發(fā)生。

rollback():如果有權(quán)限,就取消當(dāng)前的操作,否則報(bào)錯(cuò)。

cursor([cursorclass]):返回連接的游標(biāo)對(duì)象。通過(guò)游標(biāo)執(zhí)行 SQL 查詢并檢查結(jié)果。游標(biāo)比連接支持更多的方法,而且可能在程序中更好用。

close():關(guān)閉連接。此后,連接對(duì)象和游標(biāo)都不再可用了。

 

 

創(chuàng)建游標(biāo)

Python 和數(shù)據(jù)之間的連接建立起來(lái)之后,要操作數(shù)據(jù)庫(kù),就需要讓 Python 對(duì)數(shù)據(jù)庫(kù)執(zhí)行 SQL 語(yǔ)句。Python 是通過(guò)游標(biāo)執(zhí)行 SQL 語(yǔ)句的。所以,連接建立之后,就要利用連接對(duì)象得到游標(biāo)對(duì)象,方法如下:

>>> cur = conn.cursor()

 

此后,就可以利用游標(biāo)對(duì)象的方法對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。那么還得了解游標(biāo)對(duì)象的常用方法:

名稱

描述

close()

關(guān)閉游標(biāo)。之后游標(biāo)不可用

execute(query[,args])

執(zhí)行一條 SQL 語(yǔ)句,可以帶參數(shù)

executemany(query, pseq)

對(duì)序列 pseq 中的每個(gè)參數(shù)執(zhí)行 sql 語(yǔ)句

fetchone()

返回一條查詢結(jié)果

fetchall()

返回所有查詢結(jié)果

fetchmany([size])

返回 size 條結(jié)果

nextset()

移動(dòng)到下一個(gè)結(jié)果

scroll(value,mode='relative')

移動(dòng)游標(biāo)到指定行,如果 mode='relative',則表示從當(dāng)前所在行移動(dòng) value ,如果 mode='absolute',則表示從結(jié)果集的第一行移動(dòng) value

 

 

插入數(shù)據(jù)

>>> cur.execute("insert into user (name,age,mail) values (%s,%s,%s)",("lulu",18,"lulu@gmail.com"))
1L
>>>

沒(méi)有報(bào)錯(cuò),并且返回一個(gè)"1L"結(jié)果,說(shuō)明有一n 行記錄操作成功。

 

登錄MySQL,驗(yàn)證數(shù)據(jù)有沒(méi)有添加成功

mysql> select * from user;
Empty set (0.00 sec)
 
mysql>

奇怪,并沒(méi)有看到插入的那條數(shù)據(jù)!到底哪里錯(cuò)了

 

特別注意,通過(guò)"cur.execute()"對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作之后,沒(méi)有報(bào)錯(cuò),完全正確,但是不等于數(shù)據(jù)就已經(jīng)提交到數(shù)據(jù)庫(kù)中了,還必須要用到"MySQLdb.connect"連接對(duì)象的一個(gè)方法:commit(),將數(shù)據(jù)提交上去,也就是進(jìn)行了"cur.execute()"操作,要將數(shù)據(jù)提交,必須執(zhí)行:

>>> conn.commit()

 

再次登錄MySQL,看數(shù)據(jù)有沒(méi)有添加成功

mysql> select * from user;
+----+------+------+----------------+
| id | name | age  | mail           |
+----+------+------+----------------+
|  1 | lulu |   18 | lulu@gmail.com |
+----+------+------+----------------+
1 row in set (0.00 sec)
 
mysql>

 

果然如此。這就如同編寫(xiě)一個(gè)文本一樣,將文字寫(xiě)到文本上,并不等于文字已經(jīng)保留在文本文件中了,必須執(zhí)行"CTRL-S"才能保存。也就是在通過(guò) Python 操作數(shù)據(jù)庫(kù)的時(shí)候,以"execute()"執(zhí)行各種 sql 語(yǔ)句之后,要讓已經(jīng)執(zhí)行的效果保存,必須運(yùn)行連接對(duì)象的"commit()"方法。

 

 

 

插入多條數(shù)據(jù)

>>> cur.executemany("insert into user (name,age,mail) values (%s,%s,%s)",(("google",25,"g@gmail.com"),("facebook",18,"f@face.book"),("github",20,"git@hub.com"),("docker",10,"doc@ker.com")))
4L
>>>

 

mysql> select * from user;
+----+----------+------+----------------+
| id | name     | age  | mail           |
+----+----------+------+----------------+
|  1 | lulu     |   18 | lulu@gmail.com |
|  2 | google   |   25 | g@gmail.com    |
|  3 | facebook |   18 | f@face.book    |
|  4 | github   |   20 | git@hub.com    |
|  5 | docker   |   10 | doc@ker.com    |
+----+----------+------+----------------+
5 rows in set (0.00 sec)
 
mysql>

成功插入了多條記錄。在"executemany(query, pseq)"中,query 還是一條 sql 語(yǔ)句,但是 pseq 這時(shí)候是一個(gè) tuple,這個(gè) tuple 里面的元素也是 tuple,每個(gè) tuple 分別對(duì)應(yīng) sql 語(yǔ)句中的字段列表。這句話其實(shí)被執(zhí)行多次。只不過(guò)執(zhí)行過(guò)程不顯示給我們看罷了。

 

 

 

查詢

如果要從數(shù)據(jù)庫(kù)中查詢數(shù)據(jù),也用游標(biāo)方法來(lái)操作了。

>>> cur.execute("select * from user")
5L
>>> print cur.fetchall()
((1L, u'lulu', 18L, u'lulu@gmail.com'), (2L, u'google', 25L, u'g@gmail.com'), (3L, u'facebook', 18L, u'f@face.book'), (4L, u'github', 20L, u'git@hub.com'), (5L, u'docker', 10L, u'doc@ker.com'))
>>>

 

cur.execute() 從數(shù)據(jù)庫(kù)查詢出來(lái)的東西,被“保存在了 cur 所能找到的某個(gè)地方”,要找出這些被保存的東西,需要用cur.fetchall()(或者 fechone 等),并且找出來(lái)之后,做為對(duì)象存在。從上面的實(shí)驗(yàn)探討發(fā)現(xiàn),被保存的對(duì)象是一個(gè) tuple 中,里面的每個(gè)元素,都是一個(gè)一個(gè)的 tuple。因此,用 for 循環(huán)就可以一個(gè)一個(gè)拿出來(lái)了。

 

 

再次執(zhí)行一次上面的操作

>>> print cur.fetchall()
()
>>>

 

為什么結(jié)果是空的?

 

原來(lái)是通過(guò)游標(biāo)找出來(lái)的對(duì)象,在讀取的時(shí)候有一個(gè)特點(diǎn),就是那個(gè)游標(biāo)會(huì)移動(dòng)。在第一次操作了 print cur.fetchall() 后,因?yàn)槭菍⑺械亩即蛴〕鰜?lái),游標(biāo)就從第一條移動(dòng)到最后一條。當(dāng) print 結(jié)束之后,游標(biāo)已經(jīng)在最后一條的后面了。接下來(lái)如果再次打印,就空了,最后一條后面沒(méi)有東西了。

 

 

再看一個(gè)實(shí)驗(yàn)

>>> cur.execute("select * from user")
5L
>>> print cur.fetchone()
(1L, u'lulu', 18L, u'lulu@gmail.com')
>>> print cur.fetchone()
(2L, u'google', 25L, u'g@gmail.com')
>>> print cur.fetchone()
(3L, u'facebook', 18L, u'f@face.book')
>>> print cur.fetchone()
(4L, u'github', 20L, u'git@hub.com')
>>> print cur.fetchone()
(5L, u'docker', 10L, u'doc@ker.com')
>>>

 

這次不一次全部打印出來(lái)了,而是一次打印一條,可以從結(jié)果中看出來(lái),果然那個(gè)游標(biāo)在一條一條向下移動(dòng)

 

既然在操作存儲(chǔ)在內(nèi)存中的對(duì)象時(shí)候,游標(biāo)會(huì)移動(dòng),能不能讓游標(biāo)向上移動(dòng),或者移動(dòng)到指定位置呢?當(dāng)然可以,這就是scroll()

>>> print cur.fetchone()
(5L, u'docker', 10L, u'doc@ker.com')
>>> cur.scroll(-3)
>>> print cur.fetchone()
(3L, u'facebook', 18L, u'f@face.book')
>>> cur.scroll(1)
>>> print cur.fetchone()
(5L, u'docker', 10L, u'doc@ker.com')\
>>>

果然,這個(gè)函數(shù)能夠移動(dòng)游標(biāo),不過(guò)請(qǐng)仔細(xì)觀察,上面的方式是讓游標(biāo)相對(duì)與當(dāng)前位置向上或者向下移動(dòng)。即:

cur.scroll(n),或者,cur.scroll(n,"relative"):意思是相對(duì)當(dāng)前位置向上或者向下移動(dòng),n 為正數(shù),表示向下(向前),n 為負(fù)數(shù),表示向上(向后)

還有一種方式,可以實(shí)現(xiàn)“絕對(duì)”移動(dòng),不是“相對(duì)”移動(dòng):增加一個(gè)參數(shù)"absolute"

特別提醒看官注意的是,在 Python 中,序列對(duì)象是的順序是從 0 開(kāi)始的。

 

>>> cur.scroll(1,"absolute")               回到序號(hào)1,指向第2條數(shù)據(jù)
>>> print cur.fetchone()
(2L, u'google', 25L, u'g@gmail.com')
>>> 
 
>>> cur.scroll(0,"absolute")               回到序號(hào)0,指向第1條數(shù)據(jù)
>>> print cur.fetchone()
(1L, u'lulu', 18L, u'lulu@gmail.com')
>>>

 

承接上面操作,繼續(xù)

>>> print cur.fetchmany(3)
((2L, u'google', 25L, u'g@gmail.com'), (3L, u'facebook', 18L, u'f@face.book'), (4L, u'github', 20L, u'git@hub.com'))
>>>

上面這個(gè)操作,就是實(shí)現(xiàn)了從當(dāng)前位置(游標(biāo)指向 tuple 的序號(hào)為 1 的位置,即第二條記錄)開(kāi)始,含當(dāng)前位置,向下列出 3 條記錄。

 

 

 

更新數(shù)據(jù)

更新和插入一樣,都需要commit()來(lái)提交保存。

 

>>> cur.execute("update user set name=%s where id=5",("apple",))
1L
>>> cur.execute("select * from user where id=5")
1L
>>> print cur.fetchone()
(5L, u'apple', 10L, u'doc@ker.com')
>>>

 

提交更新

>>> conn.commit()
>>>

 

最后,關(guān)閉游標(biāo),關(guān)閉連接對(duì)象

>>> cur.close()
>>> conn.close()
>>>


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI