2015-04-21 4 views
17

Я вставки данных JSON в базу данных MySQLPython MySQL разъем - непрочитанные результатов найдено при использовании fetchone

Я разбора JSON, а затем вставить его в БД MySQL с помощью соединителя питона

через суд, Я могу видеть, ошибка связана с этой частью кода

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

является ли запрос слишком сложен и требует расщепления или есть другой вопрос?

Если запрос действительно слишком сложный, может ли кто-нибудь посоветовать, как лучше разделить это?

EDIT В соответствии с @ помощью ГЭРБ, в Ive пытался сбросить непрочитанные результаты

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

Вы перебираете результирующий набор и используете результат для запроса снова базы данных? Вы используете для этого один и тот же курсор? Вероятно, полезно использовать буферизованный курсор для первого. Мне нечего добавить в ответ Горда. – geertjanvdk

ответ

41

Все, что требовалось было для буферизации, чтобы оно было истинным!

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

Большое вам спасибо, вы сохранили потенциальные часы поиска ошибок. И почему это сработало, каково объяснение? – Humoyun

+0

Спаси меня. Я также был бы рад понять, почему это работает. Благодаря! – Som

+7

Причина в том, что без буферизированного курсора результаты «лениво» загружаются, что означает, что «fetchone» фактически извлекает только одну строку из полного набора результатов запроса. Когда вы снова будете использовать тот же самый курсор, он будет жаловаться на то, что у вас все еще есть n-1 результаты (где n - сумма набора результатов), ожидающих получения. Однако, когда вы используете буферизованный курсор, соединитель извлекает ВСЕ строки за кулисами, и вы просто берете один из разъема, поэтому mysql db не будет жаловаться. Надеюсь, поможет. – ilaif

11

Я смог воссоздать вашу проблему. MySQL Connector/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

Спасибо @Gord за ваше время! Интересно.Таким образом, я забочусь о более чем одной строке, и поэтому ограничение на запрос не работает. Я пытаюсь использовать метод fetchall. Тем не менее, я получаю точно такую ​​же ошибку, как и раньше: s. Ive отредактировал мой ответ, чтобы отразить это. Есть идеи? Еще раз спасибо, Gerry – LearningSlowly

+0

«' fetchall() ', чтобы избавиться от любых непрочитанных результатов» было очень полезно. –

Смежные вопросы