Python操作數(shù)據(jù)庫之MySQL
創(chuàng)新互聯(lián)是專業(yè)的建水網(wǎng)站建設(shè)公司,建水接單;提供成都網(wǎng)站設(shè)計、做網(wǎng)站,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行建水網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!一、安裝Python-MySQLdb模塊
Python-MySQLdb是一個操作數(shù)據(jù)庫的模塊,Python 通過它對 mysql 數(shù)據(jù)實現(xiàn)各種操作。
如果要源碼安裝,可以這里下載: https://pypi.Python.org/pypi/MySQL-Python/
解壓安裝包,進入解壓目錄執(zhí)行以下命令安裝
python setup.py installubuntu 下可以這么做:
sudo apt-get install build-essential Python-dev libmysqlclient-dev sudo apt-get install Python-MySQLdbpip安裝:
pip install mysql-Python安裝之后,在 python 交互模式下:
>>> import MySQLdb如果不報錯,恭喜你,已經(jīng)安裝好了。
二、操作數(shù)據(jù)庫
操作數(shù)據(jù)庫流程:
1、導(dǎo)入MySQLdb模塊
2、創(chuàng)建數(shù)據(jù)庫連接
3、執(zhí)行SQL語句和存儲過程
4、關(guān)閉數(shù)據(jù)庫連接
創(chuàng)建MySQL連接對象
>>> import MySQLdb >>> conn = MySQLdb.connect(host="localhost",user="root",passwd="123456",db="python",port=3306,charset="utf8") >>>命令含義解釋:
host:等號的后面應(yīng)該填寫 mysql 數(shù)據(jù)庫的地址,因為就數(shù)據(jù)庫就在本機上(也稱作本地),所以使用 localhost,注意引號。如果在其它的服務(wù)器上,這里應(yīng)該填寫 ip 地址。一般中小型的網(wǎng)站,數(shù)據(jù)庫和程序都是在同一臺服務(wù)器(計算機)上,就使用 localhost 了。
user:登錄數(shù)據(jù)庫的用戶名,這里一般填寫"root",還是要注意引號。當(dāng)然,如果讀者命名了別的用戶名,數(shù)據(jù)庫管理者提供了專有用戶名,就更改為相應(yīng)用戶。但是,不同用戶的權(quán)限可能不同,所以,在程序中,如果要操作數(shù)據(jù)庫,還要注意所擁有的權(quán)限。在這里用 root,就放心了,什么權(quán)限都有啦。不過,這樣做,在大型系統(tǒng)中是應(yīng)該避免的。
passwd:上述 user 賬戶對應(yīng)的登錄 mysql 的密碼。我在上面的例子中用的密碼是"123123"。不要忘記引號。
db:就是剛剛通 create 命令建立的數(shù)據(jù)庫,我建立的數(shù)據(jù)庫名字是"qiwsirtest",還是要注意引號??垂偃绻⒌臄?shù)據(jù)庫名字不是這個,就寫自己所建數(shù)據(jù)庫名字。
port:一般情況,mysql 的默認端口是 3306,當(dāng) mysql 被安裝到服務(wù)器之后,為了能夠允許網(wǎng)絡(luò)訪問,服務(wù)器(計算機)要提供一個訪問端口給它。
charset:這個設(shè)置,在很多教程中都不寫,結(jié)果在真正進行數(shù)據(jù)存儲的時候,發(fā)現(xiàn)有亂碼。這里我將 qiwsirtest 這個數(shù)據(jù)庫的編碼設(shè)置為 utf-8 格式,這樣就允許存入漢字而無亂碼了。注意,在 mysql 設(shè)置中,utf-8 寫成 utf8,沒有中間的橫線。但是在 Python 文件開頭和其它地方設(shè)置編碼格式的時候,要寫成 utf-8。切記!
Python 建立了與數(shù)據(jù)的連接,其實是建立了一個 MySQLdb.connect() 的實例對象,或者泛泛地稱之為連接對象,Python 就是通過連接對象和數(shù)據(jù)庫對話。這個對象常用的方法有:
commit():如果數(shù)據(jù)庫表進行了修改,提交保存當(dāng)前的數(shù)據(jù)。當(dāng)然,如果此用戶沒有權(quán)限就作罷了,什么也不會發(fā)生。
rollback():如果有權(quán)限,就取消當(dāng)前的操作,否則報錯。
cursor([cursorclass]):返回連接的游標對象。通過游標執(zhí)行 SQL 查詢并檢查結(jié)果。游標比連接支持更多的方法,而且可能在程序中更好用。
close():關(guān)閉連接。此后,連接對象和游標都不再可用了。
創(chuàng)建游標
Python 和數(shù)據(jù)之間的連接建立起來之后,要操作數(shù)據(jù)庫,就需要讓 Python 對數(shù)據(jù)庫執(zhí)行 SQL 語句。Python 是通過游標執(zhí)行 SQL 語句的。所以,連接建立之后,就要利用連接對象得到游標對象,方法如下:
>>> cur = conn.cursor()此后,就可以利用游標對象的方法對數(shù)據(jù)庫進行操作。那么還得了解游標對象的常用方法:
名稱 | 描述 |
close() | 關(guān)閉游標。之后游標不可用 |
execute(query[,args]) | 執(zhí)行一條 SQL 語句,可以帶參數(shù) |
executemany(query, pseq) | 對序列 pseq 中的每個參數(shù)執(zhí)行 sql 語句 |
fetchone() | 返回一條查詢結(jié)果 |
fetchall() | 返回所有查詢結(jié)果 |
fetchmany([size]) | 返回 size 條結(jié)果 |
nextset() | 移動到下一個結(jié)果 |
scroll(value,mode='relative') | 移動游標到指定行,如果 mode='relative',則表示從當(dāng)前所在行移動 value 條,如果 mode='absolute',則表示從結(jié)果集的第一行移動 value 條 |
插入數(shù)據(jù)
>>> cur.execute("insert into user (name,age,mail) values (%s,%s,%s)",("lulu",18,"lulu@gmail.com")) 1L >>>沒有報錯,并且返回一個"1L"結(jié)果,說明有一n 行記錄操作成功。
登錄MySQL,驗證數(shù)據(jù)有沒有添加成功
mysql> select * from user; Empty set (0.00 sec) mysql>奇怪,并沒有看到插入的那條數(shù)據(jù)!到底哪里錯了
特別注意,通過"cur.execute()"對數(shù)據(jù)庫進行操作之后,沒有報錯,完全正確,但是不等于數(shù)據(jù)就已經(jīng)提交到數(shù)據(jù)庫中了,還必須要用到"MySQLdb.connect"連接對象的一個方法:commit(),將數(shù)據(jù)提交上去,也就是進行了"cur.execute()"操作,要將數(shù)據(jù)提交,必須執(zhí)行:
>>> conn.commit()再次登錄MySQL,看數(shù)據(jù)有沒有添加成功
mysql> select * from user; +----+------+------+----------------+ | id | name | age | mail | +----+------+------+----------------+ | 1 | lulu | 18 | lulu@gmail.com | +----+------+------+----------------+ 1 row in set (0.00 sec) mysql>果然如此。這就如同編寫一個文本一樣,將文字寫到文本上,并不等于文字已經(jīng)保留在文本文件中了,必須執(zhí)行"CTRL-S"才能保存。也就是在通過 Python 操作數(shù)據(jù)庫的時候,以"execute()"執(zhí)行各種 sql 語句之后,要讓已經(jīng)執(zhí)行的效果保存,必須運行連接對象的"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 語句,但是 pseq 這時候是一個 tuple,這個 tuple 里面的元素也是 tuple,每個 tuple 分別對應(yīng) sql 語句中的字段列表。這句話其實被執(zhí)行多次。只不過執(zhí)行過程不顯示給我們看罷了。
查詢
如果要從數(shù)據(jù)庫中查詢數(shù)據(jù),也用游標方法來操作了。
>>> 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ù)庫查詢出來的東西,被“保存在了 cur 所能找到的某個地方”,要找出這些被保存的東西,需要用cur.fetchall()(或者 fechone 等),并且找出來之后,做為對象存在。從上面的實驗探討發(fā)現(xiàn),被保存的對象是一個 tuple 中,里面的每個元素,都是一個一個的 tuple。因此,用 for 循環(huán)就可以一個一個拿出來了。
再次執(zhí)行一次上面的操作
>>> print cur.fetchall() () >>>為什么結(jié)果是空的?
原來是通過游標找出來的對象,在讀取的時候有一個特點,就是那個游標會移動。在第一次操作了 print cur.fetchall() 后,因為是將所有的都打印出來,游標就從第一條移動到最后一條。當(dāng) print 結(jié)束之后,游標已經(jīng)在最后一條的后面了。接下來如果再次打印,就空了,最后一條后面沒有東西了。
再看一個實驗
>>> 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') >>>這次不一次全部打印出來了,而是一次打印一條,可以從結(jié)果中看出來,果然那個游標在一條一條向下移動
既然在操作存儲在內(nèi)存中的對象時候,游標會移動,能不能讓游標向上移動,或者移動到指定位置呢?當(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')\ >>>果然,這個函數(shù)能夠移動游標,不過請仔細觀察,上面的方式是讓游標相對與當(dāng)前位置向上或者向下移動。即:
cur.scroll(n),或者,cur.scroll(n,"relative"):意思是相對當(dāng)前位置向上或者向下移動,n 為正數(shù),表示向下(向前),n 為負數(shù),表示向上(向后)
還有一種方式,可以實現(xiàn)“絕對”移動,不是“相對”移動:增加一個參數(shù)"absolute"
特別提醒看官注意的是,在 Python 中,序列對象是的順序是從 0 開始的。
>>> cur.scroll(1,"absolute") 回到序號1,指向第2條數(shù)據(jù) >>> print cur.fetchone() (2L, u'google', 25L, u'g@gmail.com') >>> >>> cur.scroll(0,"absolute") 回到序號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')) >>>上面這個操作,就是實現(xiàn)了從當(dāng)前位置(游標指向 tuple 的序號為 1 的位置,即第二條記錄)開始,含當(dāng)前位置,向下列出 3 條記錄。
更新數(shù)據(jù)
更新和插入一樣,都需要commit()來提交保存。
>>> 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)閉游標,關(guān)閉連接對象
>>> cur.close() >>> conn.close() >>>另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。