PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come scrivere un frame di dati nella tabella Postgres senza utilizzare il motore SQLAlchemy?

È possibile utilizzare tali connessioni ed evitare SQLAlchemy. Sembrerà piuttosto poco intuitivo, ma sarà molto più veloce dei normali inserimenti (anche se dovessi eliminare l'ORM e fare una query generale, ad esempio con executemany ). Gli inserimenti sono lenti, anche con query non elaborate, ma vedrai che COPY è menzionato più volte in Come accelerare prestazioni di inserimento in PostgreSQL . In questo caso, le mie motivazioni per l'approccio di seguito sono:

  1. Usa COPY invece di INSERT
  2. Non fidarti di Pandas per generare l'SQL corretto per questa operazione (sebbene, come notato da Ilja Everilä, questo approccio ha effettivamente ottenuto aggiunto a Pandas in V0.24 )
  3. Non scrivere i dati su disco per creare un vero oggetto file; tieni tutto in memoria

Approccio suggerito utilizzando 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()

Questo dovrebbe essere di ordini di grandezza più veloce rispetto all'esecuzione effettiva degli inserti.