Python >> Tutoriel Python >  >> Python

Comment écrire DataFrame dans la table postgres?

À partir de pandas 0.14 (publié fin mai 2014), postgresql est pris en charge. Le sql le module utilise maintenant sqlalchemy pour prendre en charge différentes saveurs de base de données. Vous pouvez passer un moteur sqlalchemy pour une base de données postgresql (voir docs). Ex. :

from sqlalchemy import create_engine
engine = create_engine('postgresql://username:[email protected]:5432/mydatabase')
df.to_sql('table_name', engine)

Vous avez raison de dire que dans les pandas jusqu'à la version 0.13.1, postgresql n'était pas pris en charge. Si vous avez besoin d'utiliser une ancienne version de pandas, voici une version corrigée de pandas.io.sql :https://gist.github.com/jorisvandenbossche/10841234.
J'ai écrit ceci il y a un certain temps, donc je ne peux pas pleinement garantir que cela fonctionne toujours, mais la base devrait être là). Si vous placez ce fichier dans votre répertoire de travail et que vous l'importez, vous devriez pouvoir faire (où con est une connexion postgresql) :

import sql  # the patched version (file is named sql.py)
sql.write_frame(df, 'table_name', con, flavor='postgresql')

Option plus rapide :

Le code suivant copiera votre Pandas DF vers la base de données postgres beaucoup plus rapidement que la méthode df.to_sql et vous n'aurez besoin d'aucun fichier csv intermédiaire pour stocker le df.

Créez un moteur basé sur les spécifications de votre base de données.

Créez une table dans votre base de données postgres qui a le même nombre de colonnes que le Dataframe (df).

Les données dans DF seront insérées dans votre table postgres.

from sqlalchemy import create_engine
import psycopg2 
import io

si vous souhaitez remplacer la table, nous pouvons la remplacer par la méthode to_sql normale en utilisant les en-têtes de notre df, puis charger l'intégralité de la df qui prend beaucoup de temps dans la base de données.

engine = create_engine('postgresql+psycopg2://username:[email protected]:port/database')

df.head(0).to_sql('table_name', engine, if_exists='replace',index=False) #drops old table and creates new empty table

conn = engine.raw_connection()
cur = conn.cursor()
output = io.StringIO()
df.to_csv(output, sep='\t', header=False, index=False)
output.seek(0)
contents = output.getvalue()
cur.copy_from(output, 'table_name', null="") # null values become ''
conn.commit()

C'est comme ça que j'ai fait.

Il peut être plus rapide car il utilise execute_batch :

# df is the dataframe
if len(df) > 0:
    df_columns = list(df)
    # create (col1,col2,...)
    columns = ",".join(df_columns)

    # create VALUES('%s', '%s",...) one '%s' per column
    values = "VALUES({})".format(",".join(["%s" for _ in df_columns])) 

    #create INSERT INTO table (columns) VALUES('%s',...)
    insert_stmt = "INSERT INTO {} ({}) {}".format(table,columns,values)

    cur = conn.cursor()
    psycopg2.extras.execute_batch(cur, insert_stmt, df.values)
    conn.commit()
    cur.close()