python 3.8 linux mysql multi query Fehler generator raised StopIteration

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo,
um mein Projekt anzuschließen muss ich noch eine Kleinigkeit hinbekommen.
Aus der DB werte auslesen und weiter verarbeiten :)
Leider bekomme ich bei einer multi query abfrage Fehler, leider weiß ich nicht wie ich diese Fehler abfangen kann. Im Netzt habe ich bereits gesucht, gefunden habe ich das es in Python 3.7 einen Bug gab.
Ich benutze Ubuntu 20.04. Python 3.8, VI als editor.
Vielleicht hat einer mal das gleiche Problem gehabt und hat die Lösung, ich komme leider nicht weiter, vielleicht geht es so auch nicht dann muss ich das Projekt begraben oder irgendwie mit linux shell es versuchen.

Ihr seid meine letzte Hoffnung, google schon seit Montag, ich denke es muss gehen, aber leider fehlt mir an dieser stelle die Erfahrung.
Danke im Voraus.

Hier mal der Fehler aus der shell:

Traceback (most recent call last):
File "/usr/local/lib/python3.8/dist-packages/mysql/connector/cursor.py", line 486, in _execute_iter
result = next(query_iter)
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "./script.py", line 86, in <module>
funktion1()
File "./script", line 74, in abfrage_int
for result in results:
RuntimeError: generator raised StopIteration

Hier ist der Code, ich hoffe das ihr es versteht das ich nicht alles posten kann. Queries funktionieren wenn ich in der DB direkt ausführe, bekomme ich werte und keine Fehler.
versuch 2

Code: Alles auswählen

#!/usr/bin/python3
import mysql.connector
from mysql.connector.cursor import MySQLCursor

def funktion1():
   b = mysql.connector.connect(option_files="file", use_pure=True)
   cursor = db.cursor()
   sql1 = "DROP TEMPORARY TABLE IF EXISTS table1"
   sql2 = "DROP TEMPORARY TABLE IF EXISTS table2"
   sql3 = "DROP TEMPORARY TABLE IF EXISTS table3"
   
   sql4 = """
        CREATE TEMPORARY TABLE table1 SELECT und so weiter
        inhalt 
        inhalt
    """
    sql5 = "CREATE TEMPORARY TABLE table2 SELECT * FROM table1"
    sql6 = """
    CREATE TEMPORARY TABLE table3 SELECT *,'ETWAS'  FROM table1 UNION SELECT 
    inhalt
    inhalt
    """
    sql7 = "DROP TEMPORARY TABLE IF EXISTS table1"
    sql8 = "CREATE TEMPORARY TABLE table1 SELECT * FROM table3"
    sql9 = """
        SELECT * FROM (
        SELECT Inhalt
        union
        SELECT inhalt
        """
        queries = [sql1, sql2, sql3, sql4, sql5, sql6, sql7, sql8, sql9]
    #data = (etwas)

    results = cursor.execute(";".join(queries), multi=True)

    count = 1
    for result in results:
        print ("Query {0} - {1} :".format(count, result.statement))
        if result.with_rows:
            for row in result:
                print (row)
                #return row
            count = count + 1
        else:
            print ("nichts da ")
        print ()

    cursor.close()
    db.close  
versuch 1

Code: Alles auswählen

with closing(
        mysql.connector.connect(option_files="file")
    ) as connection:
        with closing(connection.cursor()) as cursor:
            cursor.execute("""
                    DROP TEMPORARY TABLE IF EXISTS table1;
                    DROP TEMPORARY TABLE IF EXISTS table2;
                    DROP TEMPORARY TABLE IF EXISTS table;

                    CREATE TEMPORARY TABLE table1 SELECT inhalt;

                    CREATE TEMPORARY TABLE table2 SELECT * FROM table1;

                    CREATE TEMPORARY TABLE table3 SELECT *,'etwas'  FROM table11 UNION SELECT inhalt;

                    DROP TEMPORARY TABLE IF EXISTS table1;

                    CREATE TEMPORARY TABLE table1 SELECT * FROM table3;

                    SELECT * FROM (
                    SELECT inhalt
                    union
                    inhalt;
                    """, multi=True
            )

            #cursor.fetchall()
            return cursor.fetchall()
            #print (cursor.fetchall())
 
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was heisst denn deiner Meinung nach "multi query error"? Und wie verhaelt sich das zu deinem Code?
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo @__deets__,
ich führe das script aus versuch2 in der shell, bekomm die werte zu sehen aber dann bricht das script mit der Meldung von oben, hier unten noch einmal,
ich verstehe nicht "RuntimeError: generator raised StopIteration", wie kann ich das abfangen, was mache ich da falsch, es bricht einfach ab obwohl es noch nicht zu ende ist.
Habe nach "generator raised StopIteration" gegoogelt, jede Lösung der jemand hatte, hat bei mir nicht geklappt.
Ich denke es liegt an dem "result = next(query_iter)" aber ich weiß leider nicht wie ich es beheben soll.
Ich möchte ungern das ganze Projekt aufgeben, es hat mir spaß gemacht, ich habe viel gelernt auch mit eurer Hilfe ab und zu.


Traceback (most recent call last):
File "/usr/local/lib/python3.8/dist-packages/mysql/connector/cursor.py", line 486, in _execute_iter
result = next(query_iter)
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "./script.py", line 86, in <module>
funktion1()
File "./script", line 74, in abfrage_int
for result in results:
RuntimeError: generator raised StopIteration
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du versuchst, mehrfach Queries auf einmal auszufuehren. Warum? Warum nicht nur einen Query pro execute?
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

@__deets__ das habe ich auch versucht aber so ging es auch nicht, bei dem Versuch habe ich gar keine werte aus der DB bekommen.
Ich versuche es morgen noch einmal mit deinem Tipp, bin aber nicht zuversichtlich, bin davon ausgegangen warum 9x wenn es einmal auch gehen sollte.
Hoffe das sich irgend einer meldet der so was schon mal bekommen hat als Fehler

hier ein bsp aus netz

Executing multiple queries with execute()

The execute() method accepts an optional keyword argument named multi. By default, it is set to False. If set to True, allows execute() to execute multiple queries separated by semicolons. When called with multi=True, the execute() method returns an iterator which can be used to access the result set produced by the queries.

Here is an example in action:

Code: Alles auswählen

import mysql.connector
from mysql.connector.cursor import MySQLCursor
from pprint import pprint

db = mysql.connector.connect(option_files='my.conf', use_pure=True)

cursor = db.cursor()

# query with format parameter style

sql1 = "select version()"

sql2 = """select Code, Name, Region, Population, Continent from
country where Continent=%s limit %s"""

sql3 = "select 1+1"

queries = [sql1, sql2, sql3]

data = ('South America', 5)

# returns an iterator
results = cursor.execute(";".join(queries), data, multi=True)

count = 1

for result in results:

    # result is a cursor object i.e result == cursor
    # so we have access to all cursor attributes and methods 

    print("Query {0} - {1} :".format(count, result.statement))

    # does query has result?
    if result.with_rows:
        for row in result:
            print(row)
        count = count + 1
    else:
        print("No result found")

    print()

cursor.close()
db.close()
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Frage ist ja, warum Du die einzelnen SQL-Befehle nicht nacheinander ausführst? Ich habe noch nichts von multi=True gehört, und sehe auch nicht wirklich einen Anwendungsfall dafür.
In Deinem konkreten Fall liegt der Fehler wahrscheinlich daran, dass Befehle wie DROP oder CREATE gar kein Ergebnis liefern.
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich habe das auch noch nie gemacht und gebraucht. Vor allem bei DML-Queries. Das man 10 Tabellen in einem Rutsch anlegen will, kann ich ja noch nachvollziehen. Aber selbst da ist es nicht noetig, und letztlich ist das halt die Ursache deiner Probleme.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

@Sirius3 ja das dachte ich auch, weil da nichts geliefert wird, aber das script bricht nach dem letztem query ab, liefert mir werte und dann bricht es ab mit der Meldung die ich schon gepostet habe.

@__deets__ ich werde das morgen mal versuchen nacheinander, eine kurze Frage noch nacheinander mit with closing geht nicht da die db Verbindung immer nach dem Befehl geschlossen wird?
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Warum sollte with closing nicht gehen? Sowohl der Cursor als auch die Connection muessen ja geschlossen werden. Was also geht da nicht?
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

@__deets_ ich bin mir nicht sicher wie man es richtig nacheinander macht mit with closing, wiederholt man dann nur curser.execute oder nur with closing oder ....
Sorry bitte nicht steinigen :)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: ja, die SQL-Befehle werden ausgeführt, die Funktionalität, mehrere Ergebnisse abzufragen, funktioniert aber nur, wenn auch jeder Befehl ein Ergebnis liefert, was bei Dir aber nicht der Fall ist.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Sirius3 hat geschrieben: Mittwoch 19. Januar 2022, 09:27 @ganja: ja, die SQL-Befehle werden ausgeführt, die Funktionalität, mehrere Ergebnisse abzufragen, funktioniert aber nur, wenn auch jeder Befehl ein Ergebnis liefert, was bei Dir aber nicht der Fall ist.
Ich denke mit multi=True sollte es gehen, man muss das "none" abfangen, da habe ich nicht so viel Erfahrung.

Es funktioniert jetzt mit eurem Tipp.
Vielen Dank @--deets__, @Sirius

Danke
Antworten