回顧一下:(1)連接數據庫;(2)建立指針;(3)通過指針插入記錄;(4)提交將插入結果保存到數據庫。在交互模式中,先溫故,再知新。
>>> #導入模塊
>>> import MySQLdb
>>> #連接數據庫
>>> conn = MySQLdb.connect(host="localhost",user="root",passwd="123123",db="mytest",port=3036,charset="utf8")
>>> #建立指針
>>> cur = conn.cursor()
>>> #插入記錄
>>> cur.execute("insert into users (username,password,email) values (%s,%s,%s)",("塔","9988","[email protected]"))
1L
>>> #提交保存
>>> conn.commit()
就在進入到數據庫,看看。
mysql> select * from users; | |||
---|---|---|---|
id | username | password | |
1 | hiekay | 123123 | [email protected] |
2 | python | 123456 | [email protected] |
3 | 111222 | [email protected] | |
4 | 222333 | [email protected] | |
5 | github | 333444 | [email protected] |
6 | docker | 444555 | [email protected] |
7 | 塔 | 9988 | [email protected] |
7 rows in set (0.00 sec)
溫故結束,開始知新。
查詢數據
在前面操作的基礎上,如果要從數據庫中查詢數據,當然也可以用指針來操作了。
>>> cur.execute("select * from users")
7L
這說明從users表彙總查詢出來了7條記錄。但是,這似乎有點不友好,告訴我7條記錄查出來了,但是在哪裏呢,看前面在'mysql>'下操作查詢命令的時候,一下就把7條記錄列出來了。怎麼顯示python在這裏的查詢結果呢?
原來,在指針實例中,還要用這樣的方法,才能實現上述功能:
- fetchall(self):接收全部的返回結果行.
- fetchmany(size=None):接收size條返回結果行.如果size的值大於返回的結果行的數量,則會返回cursor.arraysize條數據.
- fetchone():返回一條結果行.
- scroll(value, mode='relative'):移動指針到某一行.如果mode='relative',則表示從當前所在行移動value條,如果mode='absolute',則表示從結果集的第一行移動value條.
按照這些規則,嘗試:
>>> cur.execute("select * from users")
7L
>>> lines = cur.fetchall()
到這裏,還沒有看到什麼,其實已經將查詢到的記錄(把他們看做對象)賦值給變量lines了。如果要把它們顯示出來,就要用到曾經學習過的循環語句了。
>>> for line in lines:
... print line
...
(1L, u'hiekay', u'123123', u'[email protected]')
(2L, u'python', u'123456', u'[email protected]')
(3L, u'google', u'111222', u'[email protected]')
(4L, u'facebook', u'222333', u'[email protected]')
(5L, u'github', u'333444', u'[email protected]')
(6L, u'docker', u'444555', u'[email protected]')
(7L, u'\u5854', u'9988', u'[email protected]')
很好。果然是逐條顯示出來了。列位注意,第七條中的u'u5854',這裏是漢字,只不過由於我的shell不能顯示罷了,不必驚慌,不必搭理它。
只想查出第一條,可以嗎?當然可以!看下面的:
>>> cur.execute("select * from users where id=1")
1L
>>> line_first = cur.fetchone() #只返回一條
>>> print line_first
(1L, u'hiekay', u'123123', u'[email protected]')
爲了對上述過程瞭解深入,做下面實驗:
>>> cur.execute("select * from users")
7L
>>> print cur.fetchall()
((1L, u'hiekay', u'123123', u'[email protected]'), (2L, u'python', u'123456', u'[email protected]'), (3L, u'google', u'111222', u'[email protected]'), (4L, u'facebook', u'222333', u'[email protected]'), (5L, u'github', u'333444', u'[email protected]'), (6L, u'docker', u'444555', u'[email protected]'), (7L, u'\u5854', u'9988', u'[email protected]'), (8L, u'\u5854', u'9988', u'[email protected]'), (9L, u'\u5854', u'9988', u'[email protected]'), (10L, u'\u5854', u'9988', u'[email protected]'), (11L, u'\u5f20\u4e09', u'1122', u'[email protected]'))
原來,用cur.execute()從數據庫查詢出來的東西,被“保存在了cur所能找到的某個地方”,要找出這些被保存的東西,需要用cur.fetchall()(或者fechone等),並且找出來之後,做爲對象存在。從上面的實驗探討發現,被保存的對象是一個tuple中,裏面的每個元素,都是一個一個的tuple。因此,用for循環就可以一個一個拿出來了。
接着上面的操作,再打印一遍
>>> print cur.fetchall()
()
暈了!怎麼什麼是空?不是說做爲對象已經存在了內存中了嗎?難道這個內存中的對象是一次有效嗎?
通過指針找出來的對象,在讀取的時候有一個特點,就是那個指針會移動。在第一次操作了print cur.fetchall()後,因爲是將所有的都打印出來,指針就要從第一條移動到最後一條。當print結束之後,指針已經在最後一條的後面了。接下來如果再次打印,就空了,最後一條後面沒有東西了。
下面還要實驗,檢驗上面所說:
>>> cur.execute('select * from users')
7L
>>> print cur.fetchone()
(1L, u'hiekay', u'123123', u'[email protected]')
>>> print cur.fetchone()
(2L, u'python', u'123456', u'[email protected]')
>>> print cur.fetchone()
(3L, u'google', u'111222', u'[email protected]')
>>> print cur.fetchone()
這次我不一次全部打印出來了,而是一次打印一條,可以從結果中看出來,果然那個指針在一條一條向下移動呢。注意,我在這次實驗中,是重新運行了查詢語句。
那麼,既然在操作存儲在內存中的對象時候,指針會移動,能不能讓指針向上移動,或者移動到指定位置呢?這就是那個scroll()
>>> cur.scroll(1)
>>> print cur.fetchone()
(5L, u'github', u'333444', u'[email protected]')
>>> cur.scroll(-2)
>>> print cur.fetchone()
(4L, u'facebook', u'222333', u'[email protected]')
果然,這個函數能夠移動指針,不過請仔細觀察,上面的方式是讓指針相對與當前位置向上或者向下移動。即:
cur.scroll(n),或者,cur.scroll(n,"relative"):意思是相對當前位置向上或者向下移動,n爲正數,表示向下(向前),n爲負數,表示向上(向後)
還有一種方式,可以實現“絕對”移動,不是“相對”移動:增加一個參數"absolute"
特別提醒注意的是,在python中,序列對象是的順序是從0開始的。
>>> cur.scroll(2,"absolute") #回到序號是2,但指向第三條
>>> print cur.fetchone() #打印,果然是
(3L, u'google', u'111222', u'[email protected]')
>>> cur.scroll(1,"absolute")
>>> print cur.fetchone()
(2L, u'python', u'123456', u'[email protected]')
>>> cur.scroll(0,"absolute") #回到序號是0,即指向tuple的第一條
>>> print cur.fetchone()
(1L, u'hiekay', u'123123', u'[email protected]')
至此,已經熟悉了cur.fetchall()和cur.fetchone()以及cur.scroll()幾個方法,還有另外一個,接這上邊的操作,也就是指針在序號是1的位置,指向了tuple的第二條
>>> cur.fetchmany(3)
((2L, u'python', u'123456', u'[email protected]'), (3L, u'google', u'111222', u'[email protected]'), (4L, u'facebook', u'222333', u'[email protected]'))
上面這個操作,就是實現了從當前位置(指針指向tuple的序號爲1的位置,即第二條記錄)開始,含當前位置,向下列出3條記錄。
不過,python總是能夠爲我們着想的,它的指針提供了一個參數,可以實現將讀取到的數據變成字典形式,這樣就提供了另外一種讀取方式了。
>>> cur = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
>>> cur.execute("select * from users")
7L
>>> cur.fetchall()
({'username': u'hiekay', 'password': u'123123', 'id': 1L, 'email': u'[email protected]'}, {'username': u'mypython', 'password': u'123456', 'id': 2L, 'email': u'[email protected]'}, {'username': u'google', 'password': u'111222', 'id': 3L, 'email': u'[email protected]'}, {'username': u'facebook', 'password': u'222333', 'id': 4L, 'email': u'[email protected]'}, {'username': u'github', 'password': u'333444', 'id': 5L, 'email': u'[email protected]'}, {'username': u'docker', 'password': u'444555', 'id': 6L, 'email': u'[email protected]'}, {'username': u'\u8001\u9f50', 'password': u'9988', 'id': 7L, 'email': u'[email protected]'})
這樣,在元組裏面的元素就是一個一個字典。可以這樣來操作這個對象:
>>> cur.scroll(0,"absolute")
>>> for line in cur.fetchall():
... print line["username"]
...
hiekay
python
google
facebook
github
docker
塔
根據字典對象的特點來讀取了“鍵-值”。
更新數據
經過前面的操作,這個就比較簡單了,不過需要提醒的是,如果更新完畢,和插入數據一樣,都需要commit()來提交保存。
>>> cur.execute("update users set username=%s where id=2",('mypython'))
1L
>>> cur.execute("select * from users where id=2")
1L
>>> cur.fetchone()
(2L, u'mypython', u'123456', u'[email protected]')
從操作中看出來了,已經將數據庫中第二條的用戶名修改爲mypython了,用的就是update語句。
不過,要真的實現在數據庫中更新,還要運行:
>>> conn.commit()
這就大事完吉了。