2015-04-21 31 views
17

我將JSON數據到MySQL數據庫Python的MySQL的連接器 - 使用fetchone

我解析的JSON,然後將其插入MySQL數據庫使用Python連接器

經過反覆試驗時發現未讀結果,我可以看到錯誤與這段代碼

for steps in result['routes'][0]['legs'][0]['steps']: 
    query = ('SELECT leg_no FROM leg_data WHERE travel_mode = %s AND Orig_lat = %s AND Orig_lng = %s AND Dest_lat = %s AND Dest_lng = %s AND time_stamp = %s') 
    if steps['travel_mode'] == "pub_tran": 
     travel_mode = steps['travel_mode'] 
     Orig_lat = steps['var_1']['dep']['lat'] 
     Orig_lng = steps['var_1']['dep']['lng'] 
     Dest_lat = steps['var_1']['arr']['lat'] 
     Dest_lng = steps['var_1']['arr']['lng'] 
     time_stamp = leg['_sent_time_stamp'] 
    if steps['travel_mode'] =="a_pied": 
     query = ('SELECT leg_no FROM leg_data WHERE travel_mode = %s AND Orig_lat = %s AND Orig_lng = %s AND Dest_lat = %s AND Dest_lng = %s AND time_stamp = %s') 
     travel_mode = steps['travel_mode'] 
     Orig_lat = steps['var_2']['lat'] 
     Orig_lng = steps['var_2']['lng'] 
     Dest_lat = steps['var_2']['lat'] 
     Dest_lng = steps['var_2']['lng'] 
     time_stamp = leg['_sent_time_stamp'] 
    cursor.execute(query,(travel_mode, Orig_lat, Orig_lng, Dest_lat, Dest_lng, time_stamp)) 
    leg_no = cursor.fetchone()[0] 
    print(leg_no) 

我已經插入更高層次的細節,我現在搜索數據庫將與其父這一水平的信息相關聯關聯。找到這個唯一值的唯一方法是使用time_stamp通過原點和目標座標進行搜索。我相信邏輯是正確的,通過在本節之後立即打印leg_no,我可以看到在第一次檢查時出現的值是正確的

但是,當添加到代碼的其餘部分時,會導致後續部分更多的數據使用光標失敗,這個錯誤被插入 -

raise errors.InternalError("Unread result found.") 
mysql.connector.errors.InternalError: Unread result found. 

這個問題似乎類似於MySQL Unread Result with Python

是查詢太複雜,需要分割或有其他問題?

如果查詢確實太複雜了,誰能告訴如何最好地分割這個?

編輯按@戈德的幫助下,我已經企圖把未讀的結果

cursor.execute(query,(leg_travel_mode, leg_Orig_lat, leg_Orig_lng, leg_Dest_lat, leg_Dest_lng)) 
      leg_no = cursor.fetchone()[0] 
      try: 
       cursor.fetchall() 
      except mysql.connector.errors.InterfaceError as ie: 
       if ie.msg == 'No result set to fetch from.': 
        pass 
       else: 
        raise 
      cursor.execute(query,(leg_travel_mode, leg_Orig_lat, leg_Orig_lng, leg_Dest_lat, leg_Dest_lng, time_stamp)) 

但是,我仍然得到

raise errors.InternalError("Unread result found.") 
mysql.connector.errors.InternalError: Unread result found. 
[Finished in 3.3s with exit code 1] 

劃痕頭

EDIT 2 - 當我打印ie.msg,我得到 -

No result set to fetch from 
+0

你在循環結果集,並使用結果再次查詢數據庫?你使用相同的光標嗎?那麼爲第一個緩衝區使用緩衝光標可能會很好。我沒有更多的補充Gord的答案。 – geertjanvdk

回答

41

所有需要的是將緩衝設置爲true!

cursor = cnx.cursor(buffered=True) 
+1

非常感謝您,您節省了潛在的小時查錯時間。爲什麼這個工作,解釋是什麼? – Humoyun

+0

救救我吧。我也很樂意明白爲什麼會這樣。謝謝! – Som

+7

原因是沒有緩衝遊標,結果是「懶惰」加載的,這意味着「fetchone」實際上只從查詢的完整結果集中提取一行。當你再次使用相同的光標時,它會抱怨你仍然有n-1個結果(其中n是結果集數量)等待被提取。但是,當您使用緩衝遊標時,連接器會在幕後獲取所有行,並且只需從連接器中取出一行,以便mysql db不會發生抱怨。希望能幫助到你。 – ilaif

11

我能夠重新創建您的問題。 MySQL連接器/ Python顯然不喜歡它,如果你檢索多行並且在關閉遊標或使用它來檢索其他東西之前沒有抓取它們。例如

import mysql.connector 
cnxn = mysql.connector.connect(
    host='127.0.0.1', 
     user='root', 
     password='whatever', 
     database='mydb') 
crsr = cnxn.cursor() 
crsr.execute("DROP TABLE IF EXISTS pytest") 
crsr.execute(""" 
CREATE TABLE pytest (
    id INT(11) NOT NULL AUTO_INCREMENT, 
    firstname VARCHAR(20), 
    PRIMARY KEY (id) 
    ) 
""") 
crsr.execute("INSERT INTO pytest (firstname) VALUES ('Gord')") 
crsr.execute("INSERT INTO pytest (firstname) VALUES ('Anne')") 
cnxn.commit() 
crsr.execute("SELECT firstname FROM pytest") 
fname = crsr.fetchone()[0] 
print(fname) 
crsr.execute("SELECT firstname FROM pytest") # InternalError: Unread result found. 

如果你只希望(或者關心)一行,那麼你可以把LIMIT您的查詢

crsr.execute("SELECT firstname FROM pytest LIMIT 0, 1") 
fname = crsr.fetchone()[0] 
print(fname) 
crsr.execute("SELECT firstname FROM pytest") # OK now 

,或者您可以使用fetchall()擺脫任何未讀的結果在完成對您檢索的行的處理之後。

crsr.execute("SELECT firstname FROM pytest") 
fname = crsr.fetchone()[0] 
print(fname) 
try: 
    crsr.fetchall() # fetch (and discard) remaining rows 
except mysql.connector.errors.InterfaceError as ie: 
    if ie.msg == 'No result set to fetch from.': 
     # no problem, we were just at the end of the result set 
     pass 
    else: 
     raise 
crsr.execute("SELECT firstname FROM pytest") # OK now 
+0

感謝您的時間!有趣。所以,我關心不止一行,因此對查詢的限制將無法正常工作。我正在嘗試fetchall方法。但是,我得到和以前完全一樣的錯誤:s。我編輯了我的答案以反映這一點。有任何想法嗎?再次感謝Gerry – LearningSlowly

+0

「'fetchall()'擺脫任何未讀結果」非常有幫助。 –