2015-04-21 30 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()'摆脱任何未读结果”非常有帮助。 –