PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie schreibe ich einen Datenrahmen in eine Postgres-Tabelle, ohne die SQLAlchemy-Engine zu verwenden?

Sie können diese Verbindungen verwenden und SQLAlchemy vermeiden. Das wird ziemlich unintuitiv klingen, aber es wird viel schneller sein als normale Einfügungen (selbst wenn Sie das ORM fallen lassen und eine allgemeine Abfrage machen würden, z. B. mit executemany ). Einfügungen sind langsam, selbst bei Rohabfragen, aber Sie werden sehen, dass COPY wird mehrmals in How to speed up erwähnt Einfügeleistung in PostgreSQL . In diesem Fall sind meine Beweggründe für den folgenden Ansatz:

  1. Verwenden Sie COPY statt INSERT
  2. Vertrauen Sie Pandas nicht darauf, das richtige SQL für diese Operation zu generieren (obwohl dieser Ansatz, wie von Ilja Everilä angemerkt, tatsächlich in V0.24 zu Pandas hinzugefügt )
  3. Schreiben Sie die Daten nicht auf die Festplatte, um ein tatsächliches Dateiobjekt zu erstellen; alles in Erinnerung behalten

Vorgeschlagener Ansatz mit cursor.copy_from() :

import csv
import io
import psycopg2

df = "<your_df_here>"

# drop all the columns you don't want in the insert data here

# First take the headers
headers = df.columns

# Now get a nested list of values
data = df.values.tolist()

# Create an in-memory CSV file
string_buffer = io.StringIO()
csv_writer = csv.writer(string_buffer)
csv_writer.writerows(data)

# Reset the buffer back to the first line
string_buffer.seek(0)

# Open a connection to the db (which I think you already have available)
with psycopg2.connect(dbname=current_app.config['POSTGRES_DB'], 
                      user=current_app.config['POSTGRES_USER'],
                      password=current_app.config['POSTGRES_PW'], 
                      host=current_app.config['POSTGRES_URL']) as conn:
    c = conn.cursor()

    # Now upload the data as though it was a file
    c.copy_from(string_buffer, 'the_table_name', sep=',', columns=headers)
    conn.commit()

Dies sollte um Größenordnungen schneller sein, als Einfügungen tatsächlich vorzunehmen.