Ada metode DataFrame.to_sql , tetapi hanya berfungsi untuk database mysql, sqlite dan oracle. Saya tidak bisa meneruskan ke metode ini koneksi postgres atau mesin sqlalchemy.
Jawaban:
Mulai dari pandas 0.14 (dirilis akhir Mei 2014), postgresql didukung. The sql
modul sekarang menggunakan sqlalchemy
untuk mendukung rasa database yang berbeda. Anda dapat mengirimkan mesin sqlalchemy untuk database postgresql (lihat dokumen ). Misalnya:
from sqlalchemy import create_engine
engine = create_engine('postgresql://scott:tiger@localhost:5432/mydatabase')
df.to_sql('table_name', engine)
Anda benar bahwa di panda hingga versi 0.13.1 postgresql tidak didukung. Jika Anda perlu menggunakan panda versi lama, berikut adalah versi patch dari pandas.io.sql
: https://gist.github.com/jorisvandenbossche/10841234 .
Saya menulis ini beberapa waktu lalu, jadi tidak dapat sepenuhnya menjamin bahwa itu selalu berhasil, tetapi dasarnya harus ada). Jika Anda meletakkan file itu di direktori kerja Anda dan mengimpornya, maka Anda harus dapat melakukannya (di mana con
ada koneksi postgresql):
import sql # the patched version (file is named sql.py)
sql.write_frame(df, 'table_name', con, flavor='postgresql')
Sqlalchemy engine
, dapatkah saya menggunakan Postgres
koneksi yang sudah ada yang dibuat menggunakan psycopg2.connect()
?
Opsi lebih cepat:
Kode berikut akan menyalin Pandas DF Anda ke postgres DB jauh lebih cepat daripada metode df.to_sql dan Anda tidak memerlukan file csv perantara untuk menyimpan df.
Buat mesin berdasarkan spesifikasi DB Anda.
Buat tabel di postgres DB Anda yang memiliki jumlah kolom yang sama dengan Dataframe (df).
Data di DF akan dimasukkan ke dalam tabel postgres Anda.
from sqlalchemy import create_engine
import psycopg2
import io
jika Anda ingin mengganti tabel, kita dapat menggantinya dengan metode to_sql normal menggunakan header dari df kita dan kemudian memuat seluruh df yang memakan waktu besar ke dalam DB.
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()
contents
? Haruskah ini yang tertulis copy_from()
?
contents
variabelnya, semua yang lain akan bekerja dengan baik
output.seek(0)
?
Solusi panda 0.24.0+
Di Pandas 0.24.0, fitur baru diperkenalkan yang dirancang khusus untuk penulisan cepat ke Postgres. Anda dapat mempelajarinya lebih lanjut di sini: https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-sql-method
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)
method='multi'
opsi cukup cepat. Tapi ya, COPY
cara ini adalah cara tercepat saat ini.
with
menulis ke dalam buffer memori. Bagian terakhir with
adalah menggunakan pernyataan SQL dan memanfaatkan kecepatan copy_expert untuk memuat data secara massal. Apa bagian tengah yang dimulai dengan columns =
melakukan?
keys
argumen dalam psql_insert_copy
fungsi tersebut? Bagaimana cara mendapatkan kunci dan apakah kuncinya hanya nama kolom?
Table 'XYZ' already exists
. Sejauh yang saya mengerti, seharusnya tidak membuat tabel, bukan?
df.to_sql('table_name', engine, if_exists='replace', method=psql_insert_copy)
- ini membuat tabel di database Anda.
Beginilah cara saya melakukannya.
Mungkin lebih cepat karena menggunakan 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()
Untuk Python 2.7 dan Pandas 0.24.2 dan menggunakan Psycopg2
Modul Koneksi Psycopg2
def dbConnect (db_parm, username_parm, host_parm, pw_parm):
# Parse in connection information
credentials = {'host': host_parm, 'database': db_parm, 'user': username_parm, 'password': pw_parm}
conn = psycopg2.connect(**credentials)
conn.autocommit = True # auto-commit each entry to the database
conn.cursor_factory = RealDictCursor
cur = conn.cursor()
print ("Connected Successfully to DB: " + str(db_parm) + "@" + str(host_parm))
return conn, cur
Hubungkan ke database
conn, cur = dbConnect(databaseName, dbUser, dbHost, dbPwd)
Dengan asumsi dataframe sudah ada sebagai df
output = io.BytesIO() # For Python3 use StringIO
df.to_csv(output, sep='\t', header=True, index=False)
output.seek(0) # Required for rewinding the String object
copy_query = "COPY mem_info FROM STDOUT csv DELIMITER '\t' NULL '' ESCAPE '\\' HEADER " # Replace your table name in place of mem_info
cur.copy_expert(copy_query, output)
conn.commit()