2016-02-01 7 views
7

Ich versuche, MySQL-Connector als Alternative zu pymysql zu verwenden, da es mehrere Anweisungen in einer Abfrage für einige Updates, die ich machen muss (Here is my other question related to that), aber es schlägt für meinen anderen Anwendungsfall des Sendens über sehr große Select-Anweisungen.MySQL Connector Python 35 Ressource vorübergehend nicht verfügbar mit großen Abfragen?

Ich habe eine dynamisch generierte Select-Anweisung, die alle Zeilen abruft, die mit den übergebenen Werten übereinstimmen. zum Beispiel Select * from table where col_a in (val_1, val_2.... val_350,000)

ich den gleichen Fehler für meine Select-Anweisungen werden immer:

Exception in thread Thread-1: 
Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/mysql/connector/network.py", line 212, in send_compressed 
    self.sock.sendall(zip_packet) 
BlockingIOError: [Errno 35] Resource temporarily unavailable 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/threading.py", line 921, in _bootstrap_inner 
    self.run() 
    File "/Users/maldeiri/raw_data_processing/sql_retriever.py", line 22, in run 
    self.mysql_cursor.execute(self.sql_statement) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/mysql/connector/cursor.py", line 515, in execute 
    self._handle_result(self._connection.cmd_query(stmt)) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/mysql/connector/connection.py", line 488, in cmd_query 
    result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query)) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/mysql/connector/connection.py", line 261, in _send_cmd 
    packet_number) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/mysql/connector/network.py", line 215, in send_compressed 
    errno=2055, values=(self.get_address(), _strioerror(err))) 
mysql.connector.errors.OperationalError: 2055: Lost connection to MySQL server at 'database_end_point:3306', system error: 35 Resource temporarily unavailable 

Dies geschieht unabhängig davon, ob ich komprimieren haben = Wahr oder Falsch. Ich denke auch nicht, dass dies ein serverseitiges Problem ist, da ich genau die selbe Select-Anweisungen erwähnt habe, die mit pymysql laufen, der denselben Code und dieselbe Maschine ausführt.

Irgendwelche Ideen, wie ich das umgehen kann?

+0

Wo bekommen Sie die 350k Werte in den Parametern von mit? Die Datenbank? –

+0

Nein, ich habe eine rohe Textdatei, die ich habe, die sie hat (sie sind immer anders) und ich muss die entsprechenden Zeilen aus der DB ziehen, um einige Transformationen und Aktualisierungen mit anderen Rohdaten durchzuführen. –

+0

@RyanVincent Ich könnte und es ist eine Arbeit rum ich habe aber es fügt mehr Code hinzu, der wirklich nicht da sein sollte meiner Meinung nach. Was mich stört ist, dass ich weiß, dass die DB damit umgehen kann und ich weiß, dass Python damit umgehen kann, weil es mit PyMYSQL funktioniert. Es ist einfach frustrierend zu wissen, warum es nicht mit Connector-Bibliothek funktioniert. 1) Aufteilen der Werte in Gruppen von 40.000 2) Erstellen von N Anzahl von Abfragen und die Anrufe 3) Zusammenführen der Ergebnisse –

Antwort

3

Bauen Sie nicht diese horrende IN(...), sondern werfen Sie die Werte in eine Tabelle, eine pro Zeile.

Dann tun Sie eine JOIN zu der realen Tabelle, um die Zeilen zu erhalten, die Sie brauchen. (Stellen Sie sicher, dass col_a in der realen Tabelle indiziert ist, stören Sie nicht indizieren es in der zusätzlichen Tabelle.)

Wenn die riesige Liste Dupletten haben kann, sollten Sie wahrscheinlich die Liste zuerst dupieren. Sehen Sie, ob Python es leicht genug macht. Wenn nicht, könnten Sie diese Einspalte die PRIMARY KEY sein und INSERT IGNORE tun, wie Sie sie einfügen. Oder,

CREATE TABLE t (val) ENGINE=MyISAM; 
INSERT or LOAD DATA ... (no dedupping) 
SELECT rt.* FROM real_table 
    JOIN (SELECT DISTINCT val FROM t) ON rt.val = t.val; 
+0

Ich schätze die Antwort, Ich werde über dieses neue Design nachdenken und es umsetzen. Dies bringt jedoch ein neues Problem auf. Immer wenn ich versuche LOAD DATA LOCAL INFILE zu machen, bekomme ich einen Broken Pipe Fehler 'File" /usr/local/lib/python3.4/dist-packages/pymysql/connections.py ", Zeile 986, in _write_bytes self.socket.sendall (Daten) BrokenPipeError: [Errno 32] Gebrochene Leitung raise err.OperationalError (2006, "MySQL Server ist weggegangen (% r)"% (e,)) pymysql.err.OperationalError: (2006, "MySQL-Server ist weg (BrokenPipeError (32, 'Broken Pipe')))" –

+0

Überprüfen Sie 'wait_timeout',' interactive_timeout', Festplatte voll, Netzwerkproblem, 'tmpdir' auf kleinem Dateisystem. –

+0

Nun erhalte ich mysql.connector.errors.OperationalError: 2055: Verbindung zum MySQL-Server bei 'c200-aurora.cluster-cdiuhkskfb4l.us-east-1.rts.amazonaws.com:3306' verloren, Systemfehler: 35 Die Ressource ist vorübergehend nicht verfügbar, wenn versucht wird, Daten LOKALES INFIL zu laden. Dies geschieht nur manchmal. Ich habe die gleiche Load-Anweisung von mysql workbench ausprobiert und nie den Fehler bekommen ...gerade wenn ich es von Python aus anrufe. –

Verwandte Themen