歡迎您光臨本站 註冊首頁

解決pymysql cursor.fetchall() 獲取不到數據的問題

←手機掃碼閱讀     qp18502452 @ 2020-06-10 , reply:0

1.之前的寫法(不報錯):

data = cursor.fetchall()
 data_name = data[0]['task_type']

2.簡潔的寫法(報錯):

data = cursor.fetchall()[0]['task_type']

用 2 的寫法報錯之後,一度懷疑是數據庫出了問題。不服氣用pycharm 的watch功能進行調試,更是錯上加錯。

錯誤原因:

cursor.fetchall() 相當於從數據庫取數據,但是取完就沒有了,再下一行繼續 cursor.fetchall(),取到的就只是空列表。他和變量不一樣,不能重複查詢,推薦第一種寫法,將數據取出來之後,放到一個變量裡,再進行處理。

用watch 功能更是添亂。

補充知識:VScode pymysql模塊fetchall方法取不到值bug

這個問題是個很神奇的東西,簡單來說就是用fetchall()取cusor中的_rows的值,明明_rows裡面存在值,但依然取出來為空,看了一會pymysql裡cursor裡的源碼,大概地瞭解到這個bug的表面原因:

原因:

cursor,在其內部有個rownumber的變量,作用大概就是“遊標”的意思吧,如果你是用fetchone()方法,取出來的就是第一個數,然後將遊標移到下一位,下次去取就是從遊標的位置開始還不是從_rows裡的起始位置開始,fetchmany()同理,另外,cursor中還提供了直接移動遊標的方法,也就是scroll方法,接下來,我們具體分析下fetchall的代碼:

    def fetchall(self):    """Fetch all the rows"""    self._check_executed()    if self._rows is None:     return ()    if self.rownumber:     result = self._rows[self.rownumber:]    else:     result = self._rows    self.rownumber = len(self._rows)    return result

 

代碼簡潔明瞭,如果_rows裡面沒值,確實是在數據庫中沒查到,那就返回空,如果有遊標,那從遊標位置開始取,否則,直接返回_rows整個結果集,然後將遊標移到最後,問題將出在這,我可以確定每次執行完查詢以後,我都關閉了遊標,未關閉db連接,並且,不會針對同一次查詢多次fetchall(),但是在執行的時候,有時候即使是第一次fetchall()方法,遊標依然在最後,然後我給cursor中所有的rownumber的賦值語句全部加了斷點,這些斷點都沒執行的情況下,rownumber的值依然變了,這足以確定不是pymysql的代碼問題

解決方案:

這就更能確定是vscode的編譯模塊的問題了,新建一個py文件,將原代碼原封不動的複製過去,再執行,竟然將這麼好了?!就是這麼神奇,什麼代碼沒動,換個文件將好了,然後,這個bug是偶發性的,並不是每次fetchall()都會出現這種情況


[qp18502452 ] 解決pymysql cursor.fetchall() 獲取不到數據的問題已經有324次圍觀

http://coctec.com/docs/mysql/show-post-237834.html