2016-09-12 7 views
0

Ich versuche, eine Tabelle zu schneiden und nur ~ 3000 Zeilen von Daten mit SQLAlchemy einfügen, und es ist sehr langsam (~ 10 Minuten).SQLAlchemy Core-Masseneinfügung langsam

Ich folgte den Empfehlungen zu diesem doc und gehebelten sqlalchemy Kern, um meine Einsätze zu tun, aber es läuft immer noch sehr sehr langsam. Was sind mögliche Täter für mich zu sehen? Die Datenbank ist eine postgres RDS-Instanz. Vielen Dank!

engine = sa.create_engine(db_string, **kwargs, pool_recycle=3600) 
with engine.begin() as conn: 
      conn.execute("TRUNCATE my_table") 
      conn.execute(
       MyTable.__table__.insert(), 
       data #where data is a list of dicts 
      ) 
+0

Haben Sie einen Primärschlüssel? ist das eine Menge von Tabellen mit Querverweisen? 10 Minuten zum Einfügen von 3k Zeilen scheint sehr exzessiv ... wie groß ist eine Zeile? Sie Datenbank läuft remote (dh nicht localhost ...) (das würde definitiv die Dinge verlangsamen ... wie viel, wahrscheinlich hängt von der Netzwerklatenz) ? –

+0

Ja, ich habe einen Primärschlüssel, den ich über sa/alambic als natürlichen Schlüssel der Größe 100 gesetzt habe. Allerdings habe ich auch versucht, ihn mit einem Ersatz-Integer-Schlüssel auszuschalten und hatte ähnliche Leistungsprobleme. Meine Zeile besteht aus 6 Spalten mit Strings. Die DB ist remote (in AWS), also kann das Netzwerk damit etwas zu tun haben. – ResrieC

+0

Dies benutzt das 'executemany'-Feature, das für psycopg2 ein verklärtes' execute' in einer 'for'-Schleife ist. Siehe [diese Frage] (http://stackoverflow.com/questions/8134602/psycopg2-insert-multiple-rows-with-one-query). – univerio

Antwort

1

Ich war bummed, als ich das sah keine Antwort hätte ... Ich lief in das exakt gleiche Problem den anderen Tag: Der Versuch, Masseneinsatz über Millionen von Zeilen zu einer Postgres RDS Instanz mit CORE . Es dauerte Stunden.

Als Abhilfe kann ich am Ende meinen eigenen Bulk-Insert-Skript bis zu schreiben, die die rohe SQL selbst erzeugt:

bulk_insert_str = [] 
for entry in entry_list: 
    val_str = "('{}', '{}', ...)".format(entry["column1"], entry["column2"], ...) 
    bulk_insert_str.append(val_str) 

engine.execute(
    """ 
    INSERT INTO my_table (column1, column2 ...) 
    VALUES {} 
    """.format(",".join(bulk_insert_str)) 
) 

Während hässlich, das gab mir die Leistung, die wir (~ 500.000 Zeilen/Minute) benötigen

Haben Sie eine CORE-basierte Lösung gefunden? Wenn nicht, hoffe das hilft!

AKTUALISIERUNG: Ich habe mein altes Skript in eine Ersatz-EC2-Instanz verschoben, die wir nicht verwendet haben, wodurch das Problem mit der langsamen Leistung behoben wurde. Sie sind sich nicht sicher, was Ihre Einrichtung ist, aber offensichtlich gibt es einen Netzwerk-Overhead bei der Kommunikation mit RDS über eine externe (nicht AWS) Verbindung.

+1

Oh, hmm. Ich habe versucht, mit meinen Daten sicher zu sein und 'sqlalchemy.text()' um mein 'insert' zu verwenden, und parametriere dann die Werte (zB' engine.execute (sqlalchemy.text (insert_str), ** Parameter) ') aber es scheint, als ob 'sqlalchemy.text()' eine Menge Zeit braucht ... Vielleicht Vorsicht in den Wind zu werfen und nur darin Werte zu schlagen, ist der Weg zu gehen? * Zuckungen * (Um klar zu sein: nicht zu kritisieren; es könnte tatsächlich meine beste Lösung sein. Schreckt mich nur ein wenig) – dwanderson