web-dev-qa-db-ja.com

Pythonで作成されたデータフレームの結果であるデータをRedshiftに書き込む方法は?

Pythonのデータフレームがあります。このデータを新しいテーブルとしてRedshiftに書き込むことはできますか? Redshiftへのdb接続を正常に作成し、簡単なsqlクエリを実行できます。次に、データフレームを書き込む必要があります。

18
Sahil

to_sqlを使用して、データをRedshiftデータベースにプッシュできます。 SQLAlchemyエンジンを介したデータベースへの接続を使用してこれを行うことができました。 index = False呼び出しでto_sqlを設定してください。テーブルが存在しない場合は作成されます。テーブルを置き換えるか、テーブルに追加するか、テーブルが既に存在する場合は失敗するかを指定できます。

from sqlalchemy import create_engine
import pandas as pd

conn = create_engine('postgresql://username:[email protected]:5439/yourdatabase')

df = pd.DataFrame([{'A': 'foo', 'B': 'green', 'C': 11},{'A':'bar', 'B':'blue', 'C': 20}])

df.to_sql('your_table', conn, index=False, if_exists='replace')

SQLAlchemyを介してRedshiftに接続するには、 pip install psycopg2 が必要になる場合があることに注意してください。

to_sqlドキュメント

32
Andrew
import pandas_redshift as pr

pr.connect_to_redshift(dbname = <dbname>,
                        Host = <Host>,
                        port = <port>,
                        user = <user>,
                        password = <password>)

pr.connect_to_s3(aws_access_key_id = <aws_access_key_id>,
                aws_secret_access_key = <aws_secret_access_key>,
                bucket = <bucket>,
                subdirectory = <subdirectory>)

# Write the DataFrame to S3 and then to redshift
pr.pandas_to_redshift(data_frame = data_frame,
                        redshift_table_name = 'gawronski.nba_shots_log')

詳細: https://github.com/agawronski/pandas_redshift

9
AidanGawronski

S3にアクセスできると仮定すると、このアプローチは機能するはずです。

ステップ1:DataFrameをcsvとしてS3に書き込みます(これにはAWS SDK boto3を使用します)
ステップ2:DataFrameからRedshiftテーブルの列、データ型、キー/インデックスを知っているので、create tableスクリプトを生成し、Redshiftにプッシュして空を作成できるはずです。表
ステップ3:Python環境からRedshiftにcopyコマンドを送信して、ステップ3で作成した空のテーブルにデータをコピーします

常に魅力のように機能します。

ステップ4:クラウドストレージの人々が大声で叫ぶ前に、S3からcsvを削除します

これを数回繰り返している場合、関数内の4つのステップすべてをラップすることで整頓されます。

4
BigPanda

pandas df.to_sql()を使用しようとしましたが、非常に遅くなりました。50行を挿入するのに10分以上かかりました。 this 未解決の問題を参照してください。 (執筆時点)

ブレイズエコシステムから odo を使用してみました(問題の議論の推奨事項に従って)が、ProgrammingErrorに直面しましたが、調査する必要はありませんでした。

最後に働いたもの:

import psycopg2

# Fill in the blanks for the conn object
conn = psycopg2.connect(user = 'user',
                              password = 'password',
                              Host = 'Host',
                              dbname = 'db',
                              port = 666)
cursor = conn.cursor()

args_str = b','.join(cursor.mogrify("(%s,%s,...)", x) for x in Tuple(map(Tuple,np_data)))
cursor.execute("insert into table (a,b,...) VALUES "+args_str.decode("utf-8"))

cursor.close()
conn.commit()
conn.close()

うん、普通の古いpsycopg2。これはnumpy配列用ですが、dfからndarrayへの変換はそれほど難しくないはずです。これにより、約3k行/分が得られました。

ただし、他のチームメイトからの推奨事項による最速のソリューションは、データフレームをTSV/CSVとしてS3クラスターにダンプしてからコピーした後にCOPYコマンドを使用することです。本当に巨大なデータセットをコピーする場合は、これを調査する必要があります。 (試してみると、ここで更新します)

4
Gaurav

以前はpandas to_sql()関数に依存していましたが、速度が遅すぎます。最近、次のことに切り替えました。

_import pandas as pd
import s3fs # great module which allows you to read/write to s3 easily
import sqlalchemy

df = pd.DataFrame([{'A': 'foo', 'B': 'green', 'C': 11},{'A':'bar', 'B':'blue', 'C': 20}])

s3 = s3fs.S3FileSystem(anon=False)
filename = 'my_s3_bucket_name/file.csv'
with s3.open(filename, 'w') as f:
    df.to_csv(f, index=False, header=False)

con = sqlalchemy.create_engine('postgresql://username:[email protected]:5439/yourdatabase')
# make sure the schema for mytable exists

# if you need to delete the table but not the schema leave DELETE mytable
# if you want to only append, I think just removing the DELETE mytable would work

con.execute("""
    DELETE mytable;
    COPY mytable
    from 's3://%s'
    iam_role 'arn:aws:iam::xxxx:role/role_name'
    csv;""" % filename)

_

ロールはS3へのredshiftアクセスを許可する必要があります。詳細については、 here を参照してください

300KBファイル(12000x2データフレーム)の場合、pandas to_sql() functionで取得していた8分に比べて4秒かかります。

2
erncyp

この会話のためにPostgres = RedShift 2つのオプションがあります:

オプション1:

パンダから: http://pandas.pydata.org/pandas-docs/stable/io.html#io-sql

Pandas.io.sqlモジュールは、データ取得を容易にし、DB固有のAPIへの依存を減らすためのクエリラッパーのコレクションを提供します。データベースの抽象化は、SQLAlchemyがインストールされている場合に提供されます。さらに、データベース用のドライバーライブラリが必要になります。そのようなドライバーの例は、PostgreSQLの場合はpsycopg2、MySQLの場合はpymysqlです。

データフレームの作成

次のデータがDataFrameデータにあると仮定すると、to_sql()を使用してデータベースに挿入できます。

id  Date    Col_1   Col_2   Col_3
26  2012-10-18  X   25.7    True
42  2012-10-19  Y   -12.4   False
63  2012-10-20  Z   5.73    True

In [437]: data.to_sql('data', engine)

一部のデータベースでは、大きなDataFrameを書き込むと、パケットサイズの制限を超えているためエラーが発生する可能性があります。これは、to_sqlを呼び出すときにchunksizeパラメーターを設定することで回避できます。たとえば、次の例では、一度に1000行のバッチでデータベースにデータを書き込みます。

In [438]: data.to_sql('data_chunked', engine, chunksize=1000)

オプション2

または、dataと呼ばれるデータフレームがある場合、単純にiterrowsを使用してループします:

for row in data.iterrows():

次に、各行をデータベースに追加します。行ごとに挿入する代わりにコピーを使用します。これははるかに高速になるためです。

http://initd.org/psycopg/docs/usage.html#using-copy-to-and-copy-from

0