df_name.to_sql('table_name',
schema = 'public',
con = engine,
index = False,
if_exists = 'replace')
Ich schreibe einen Datenrahmen mit 500.000 Zeilen in eine Postgres-AWS-Datenbank und es dauert sehr, sehr lange, die Daten durchzuschieben.
Es ist ein ziemlich großer SQL-Server und meine Internetverbindung ist ausgezeichnet, daher habe ich ausgeschlossen, dass diese zum Problem beitragen.
Im Vergleich dazu ist csv2sql oder die Verwendung von cat und Piping in psql in der Befehlszeile viel schneller.
Siehe hier: http://stackoverflow.com/questions/33816918/write-large-pandas-dataframes-to-sql-server-database
Mit SQLServer müssen Sie aus Effizienzgründen über CSV mit einem Massen-Upload importieren
Dies könnte hilfreich sein: http://odo.pydata.org/en/latest/perf.html
ODO würde bei mir nicht funktionieren, es erzeugt Fehler, die ich nicht beheben konnte, aber d6tstack hat einwandfrei funktioniert https://github.com/d6t/d6tstack/blob/master/examples-sql.ipynb. Sie können mit Pandas vorverarbeiten und es wird postgres COPY FROM verwendet, um den Import schnell zu machen. Funktioniert gut mit RDS-Postgres.
Fügen Sie diesen Code unter engine = create_engine(connection_string)
:
from sqlalchemy import event
@event.listens_for(e, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
if executemany:
cursor.fast_executemany = True
cursor.commit()
In meinem Code dauerte die Ausführung der to_sql
-Funktion 7 Minuten, und jetzt dauert es nur noch 5 Sekunden;)
Danke @llautert!
Das hat sehr geholfen!
# dont forget to import event
from sqlalchemy import event, create_engine
engine = create_engine(connection_string)
@event.listens_for(engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
if executemany:
cursor.fast_executemany = True
cursor.commit()
Ich habe versucht, dieses Update auszuführen, habe jedoch eine Fehlermeldung erhalten:
AttributeError: 'psycopg2.extensions.cursor' object has no attribute 'fast_executemany'
Weiß jemand was los ist?
Hey @ tim-sauchuk, der ebenfalls auf denselben Fehler stößt, obwohl ich eine Lösung gefunden habe, die hervorragend funktioniert und eine leichte Bearbeitung der Datei pandas.io.sql.py beinhaltet (löschen Sie einfach die .pyc-Datei aus __pycache__, bevor Sie sie erneut importieren um sicherzustellen, dass die neue Version in die komprimierte Datei geschrieben wird)
Hey @ tim-sauchuk, der ebenfalls auf den gleichen Fehler stößt, obwohl ich eine Lösung gefunden habe, die hervorragend funktioniert und eine leichte Bearbeitung der Datei pandas.io.sql.py beinhaltet (löschen Sie einfach die .pyc-Datei aus pycache, bevor Sie sie erneut importieren um sicherzustellen, dass die neue Version in die komprimierte Datei geschrieben wird)
8953
Das von @ bsaunders23 erwähnte Problem Nr. 8953 zeigt auch einen Weg zum "Affen-Patch" (zur Laufzeit beheben). Ich habe es versucht, und ein 20k-Datensatz, dessen Hochladen mehr als 10 Minuten dauerte, dauerte nur 4 Sekunden.
Danke @llautert!
Das hat sehr geholfen!# dont forget to import event from sqlalchemy import event, create_engine engine = create_engine(connection_string) @event.listens_for(engine, 'before_cursor_execute') def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany): if executemany: cursor.fast_executemany = True cursor.commit()
Weiß jemand, wie ich diese Lösung in einer Klasse mit einer self.engine-Instanz implementieren kann?
Weiß jemand, wie ich diese Lösung in einer Klasse mit einer self.engine-Instanz implementieren kann?
Funktioniert für mich unter Bezugnahme auf self.engine
Beispiel:
self.engine = sqlalchemy.create_engine(connectionString, echo=echo)
self.connection = self.engine.connect()
@event.listens_for(self.engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
print("Listen before_cursor_execute - executemany: %s" % str(executemany))
if executemany:
cursor.fast_executemany = True
cursor.commit()
Funktioniert bei mir nicht Welche Pandas und SQLalchemy-Version verwenden Sie?
Ich habe versucht, sqlalchemy auszuführen: 1.2.4-py35h14c3975_0 und 1.2.11-py35h7b6447c_0
aber ich bekomme
AttributeError: Das Objekt 'psycopg2.extensions.cursor' hat kein Attribut 'fast_executemany'.
@ dean12 @llautert
Wie sieht der Funktionsaufruf in diesem Zusammenhang aus? Oder mit anderen Worten, was verwenden Sie für die Argumente, um die Tabelle erfolgreich hochzuladen?
<# dont forget to import event
from sqlalchemy import event, create_engine
engine = create_engine(connection_string)
@event.listens_for(engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
if executemany:
cursor.fast_executemany = True
cursor.commit()>``
Ich habe versucht, sqlalchemy auszuführen: 1.2.4-py35h14c3975_0 und 1.2.11-py35h7b6447c_0
aber ich bekomme
AttributeError: Das Objekt 'psycopg2.extensions.cursor' hat kein Attribut 'fast_executemany'.
Sie verwenden psycopg2, einen Postgresql-Treiber. Dieses Problem und dieser Fix betreffen Microsoft SQL Server mit dem pyodbc-Treiber.
Was ist mit dem Parameter 'dtype'?
Weiß jemand, wie ich diese Lösung in einer Klasse mit einer self.engine-Instanz implementieren kann?
Funktioniert für mich unter Bezugnahme auf
self.engine
Beispiel:
self.engine = sqlalchemy.create_engine(connectionString, echo=echo) self.connection = self.engine.connect() @event.listens_for(self.engine, 'before_cursor_execute') def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany): print("Listen before_cursor_execute - executemany: %s" % str(executemany)) if executemany: cursor.fast_executemany = True cursor.commit()
Hast du herausgefunden wie?
Ich denke, die richtige Antwort sollte sein, https://docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2 -batch-mode-fast-execute zu verwenden, wenn Sie versuchen, pandas dataframe
zu sparen postgres
Eine neue Version von Pandas enthält den Parameter method
, der als "Multi" ausgewählt werden kann. Dadurch wird der Code viel schneller ausgeführt.
fast_executemany
kann jetzt in einem einzigen Schritt ausgeführt werden (sqlalchemy> = 1.3.0):
engine = sqlalchemy.create_engine(connection_string, fast_executemany=True)
Vielleicht lohnt es sich, es irgendwo in den Dokumenten oder mit einem Beispiel zu erwähnen? Es ist ein besonderer Fall, der nicht mit Pandas zusammenhängt, aber es ist eine kleine Ergänzung, die in vielen Fällen die Leistung drastisch verbessern könnte.
Eine neue Version von Pandas enthält den Parameter
method
, der als "Multi" ausgewählt werden kann. Dadurch wird der Code viel schneller ausgeführt.
Sie würden denken, dass das Setzen des Parameters chunksize
ausreichen würde, um to_sql
Batch einzufügen, aber nein.
Eine Alternative für MS SQL-Benutzer ist die Verwendung von turbodbc.Cursor.insertmanycolumns
. Dies habe ich im verknüpften StackOverflow-Beitrag erklärt: https://stackoverflow.com/a/62671681/1689261
Für zukünftige Leser gibt es zwei Möglichkeiten, einen 'batch_mode' für to_sql zu verwenden. Das Folgende sind die zwei Kombinationen:
create_engine(connection_string, executemany_mode='batch', executemany_batch_page_size=x)
oder
create_engine(connection_string, executemany_mode='values', executemany_values_page_size=x)
Details zu diesen Argumenten finden Sie hier: https://docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2 -fast-execute-helpers
Für Postgres-Benutzer empfehle ich, method
auf einen aufrufbaren
Aufrufbar mit Signatur (pd_table, conn, keys, data_iter): Dies kann verwendet werden, um eine leistungsfähigere Einfügemethode zu implementieren, die auf bestimmten Backend-Dialektfunktionen basiert.
und rufen Sie die Funktion aus dem Beispielcode hier auf: https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#insertion -method and
Die Verwendung von COPY FROM
ist wirklich viel schneller 🚀
Hilfreichster Kommentar
Fügen Sie diesen Code unter
engine = create_engine(connection_string)
:In meinem Code dauerte die Ausführung der
to_sql
-Funktion 7 Minuten, und jetzt dauert es nur noch 5 Sekunden;)