Il existe une méthode DataFrame.to_sql, mais elle ne fonctionne que pour les bases de données mysql, sqlite et Oracle. Je ne peux pas passer à cette méthode postgres connection ou sqlalchemy engine.
Postgresql est pris en charge à partir de pandas 0.14 (publié fin mai 2014). Le module sql
utilise désormais sqlalchemy
pour prendre en charge différents types de bases de données. Vous pouvez passer un moteur sqlalchemy pour une base de données postgresql (voir docs ).
from sqlalchemy import create_engine
engine = create_engine('postgresql://scott:tiger@localhost:5432/mydatabase')
df.to_sql('table_name', engine)
Vous avez raison de dire que dans pandas jusqu’à la version 0.13.1, postgresql n’était pas pris en charge. Si vous devez utiliser une version plus ancienne de pandas, voici une version corrigée de pandas.io.sql
: https://Gist.github.com/jorisvandenbossche/10841234 .
Je l’ai écrit il ya quelque temps, je ne peux donc pas garantir que cela fonctionne toujours, mais la base devrait être là). Si vous mettez ce fichier dans votre répertoire de travail et l'importez, vous devriez pouvoir le 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 va copier votre Pandas DF dans une base de données postgres beaucoup plus rapide que la méthode df.to_sql et vous n'aurez besoin d'aucun fichier csv intermédiaire pour stocker le fichier df. .
Créez un moteur basé sur vos spécifications de base de données.
Créez une table dans votre base de données postgres comportant un nombre de colonnes égal à celui du 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 fichier df, puis charger le fichier df, qui prend beaucoup de temps et qui prend beaucoup de temps.
engine = create_engine('postgresql+psycopg2://username:password@Host:port/database')
df.head(0).to_sql('table_name', engine, if_exists='replace',index=False) #truncates the 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()
Voici comment je le fais, je peux ê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()
cur = db_conn.cursor()
psycopg2.extras.execute_batch(cur, insert_stmt, df.values)
conn.commit()
cur.close()
Solution Pandas 0.24.0+
Dans Pandas 0.24.0, une nouvelle fonctionnalité spécialement conçue pour les écritures rapides dans Postgres a été introduite. Vous pouvez en apprendre plus à ce sujet ici: https://pandas.pydata.org/pandas -docs/stable/user_guide/io.html # méthode io-sql
import csv
from io import StringIO
from sqlalchemy import create_engine
def psql_insert_copy(table, conn, keys, data_iter):
# gets a DBAPI connection that can provide a cursor
dbapi_conn = conn.connection
with dbapi_conn.cursor() as cur:
s_buf = StringIO()
writer = csv.writer(s_buf)
writer.writerows(data_iter)
s_buf.seek(0)
columns = ', '.join('"{}"'.format(k) for k in keys)
if table.schema:
table_name = '{}.{}'.format(table.schema, table.name)
else:
table_name = table.name
sql = 'COPY {} ({}) FROM STDIN WITH CSV'.format(
table_name, columns)
cur.copy_expert(sql=sql, file=s_buf)
engine = create_engine('postgresql://myusername:mypassword@myhost:5432/mydatabase')
df.to_sql('table_name', engine, method=psql_insert_copy)