web-dev-qa-db-fra.com

Python MySQL - résultat non lu détecté lors de l'utilisation de fetchone

J'insère des données JSON dans une base de données MySQL

J'analyse le fichier JSON, puis je l'insère dans une base de données MySQL à l'aide du connecteur python

À travers le procès, je peux voir que l'erreur est associée à ce morceau de code

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)

J'ai inséré des détails de niveau supérieur et je cherche maintenant dans la base de données pour associer ces informations de niveau inférieur à son parent. Le seul moyen de trouver cette valeur unique consiste à effectuer une recherche via les coordonnées d'origine et de destination avec time_stamp. Je crois que la logique est bonne et en imprimant le leg_no immédiatement après cette section, je peux voir les valeurs qui semblent correctes lors de la première inspection

Toutefois, une fois ajouté au reste du code, les sections suivantes dans lesquelles davantage de données sont insérées à l'aide du curseur échouent avec cette erreur -

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

Le problème semble similaire à Résultat non lu de MySQL avec Python

La requête est-elle trop complexe et doit-elle être scindée ou existe-t-il un autre problème?

Si la requête est en effet trop complexe, quelqu'un peut-il indiquer la meilleure façon de scinder cette question?

EDIT Selon l'aide de Gord, Ive a essayé de vider tous les résultats non lus

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))

Mais je reçois encore

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

se gratte la tête

EDIT 2 - quand j'imprime le ie.msg, je reçois -

No result set to fetch from
35
LearningSlowly

Tout ce qui était nécessaire était pour buffered être défini sur true!

cursor = cnx.cursor(buffered=True)
109
LearningSlowly

J'ai pu recréer votre problème. Apparemment, MySQL Connector/Python ne l'aime pas si vous récupérez plusieurs lignes et que vous ne les récupérez pas toutes avant de fermer le curseur ou de l'utiliser pour récupérer d'autres éléments. Par exemple

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.

Si vous ne vous attendez qu'à une seule ligne, vous pouvez mettre un LIMIT sur votre requête

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

ou vous pouvez utiliser fetchall() pour supprimer tous les résultats non lus une fois que vous avez fini de travailler avec les lignes que vous avez récupérées.

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
18
Gord Thompson