回答:
pandas 0.14(2014年5月末にリリース)以降、postgresqlがサポートされています。sql
モジュールは現在使用してsqlalchemy
異なるデータベースのフレーバーをサポートします。postgresqlデータベースのsqlalchemyエンジンを渡すことができます(docsを参照)。例えば:
from sqlalchemy import create_engine
engine = create_engine('postgresql://scott:tiger@localhost:5432/mydatabase')
df.to_sql('table_name', engine)
バージョン0.13.1までのパンダではpostgresqlはサポートされていなかったのはあなたです。古いバージョンのパンダを使用する必要がある場合は、次のパッチを適用したバージョンがありpandas.io.sql
ます:https : //gist.github.com/jorisvandenbossche/10841234。
私はこれを少し前に書いたので、それが常に機能することを完全に保証することはできませんが、基礎はそこにあるはずです)。そのファイルを作業ディレクトリに入れてインポートすると、次のことができるはずです(con
postgresql接続があります)。
import sql # the patched version (file is named sql.py)
sql.write_frame(df, 'table_name', con, flavor='postgresql')
Sqlalchemy engine
、を使用してPostgres
作成された既存の接続を使用できpsycopg2.connect()
ますか?
より高速なオプション:
次のコードは、Pandas DFをdf.to_sqlメソッドよりもはるかに高速にpostgres DBにコピーし、dfを格納するための中間csvファイルを必要としません。
DB仕様に基づいてエンジンを作成します。
データフレーム(df)と同じ数の列を持つpostgres DBにテーブルを作成します。
DFのデータがpostgresテーブルに挿入されます。
from sqlalchemy import create_engine
import psycopg2
import io
テーブルを置き換える場合は、dfのヘッダーを使用して通常のto_sqlメソッドで置き換え、時間のかかる大きなdf全体を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
は何をしますか?これで書かれたものである必要がありcopy_from()
ますか?
contents
変数を無視するだけで、他のすべては問題なく機能するはずです
output.seek(0)
ますか?
Pandas 0.24.0+ソリューション
Pandas 0.24.0では、Postgresへの高速書き込み専用に設計された新機能が導入されました。詳しくは、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'
場合、追加オプションは十分高速です。しかし、はい、このCOPY
方法が現在最速の方法です。
with
は、メモリ内バッファへの書き込みです。の最後の部分でwith
は、SQLステートメントを使用し、copy_expertの速度を利用してデータをバルクロードします。始めることから始まる中間部分は何columns =
ですか?
keys
はpsql_insert_copy
関数の引数を説明できますか?どのようにしてキーを取得し、キーは列名だけですか?
Table 'XYZ' already exists
。私が理解している限り、テーブルを作成するべきではありませんか?
df.to_sql('table_name', engine, if_exists='replace', method=psql_insert_copy)
-これにより、データベースにテーブルが作成されます。
これは私がやった方法です。
次を使用しているため、より高速になる可能性があります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()
Python 2.7およびPandas 0.24.2で、Psycopg2を使用する場合
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
データベースに接続する
conn, cur = dbConnect(databaseName, dbUser, dbHost, dbPwd)
データフレームがすでに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()