したがって、Python 3.5のpsycopg2ドライバを使用してPandas 19.xに次のコードを実行しています。psycopg2 Postgresメモリバッファを使用したPandas read_csvのCOPY EXPERTがValueErrorで失敗する
buf = io.StringIO()
cursor = conn.cursor()
sql_query = 'COPY ('+ base_sql + ' limit 100) TO STDOUT WITH CSV HEADER'
cursor.copy_expert(sql_query, buf)
df = pd.read_csv(buf.getvalue(),engine='c')
buf.close()
メモリバッファから読み取るときにチャンクを吹くread_csv:
pandas\parser.pyx in pandas.parser.TextReader.__cinit__ (pandas\parser.c:4175)()
pandas\parser.pyx in pandas.parser.TextReader._setup_parser_source (pandas\parser.c:8333)()
C:\Users\....\AppData\Local\Continuum\Anaconda3\lib\genericpath.py in exists(path)
17 """Test whether a path exists. Returns False for broken symbolic links"""
18 try:
---> 19 os.stat(path)
20 except OSError:
21 return False
ValueError: stat: path too long for Windows
Uh..wotパス? bufはメモリ内にあります。私はここで何が欠けていますか?
参考までに、コピー先が予期したとおりに動作しているようです。以下の回答には、以下の
おかげ
ソリューションコードは、私のクエリの速度が500%低下した。この方法で、私のメモリ使用量を使用して倍増しました。ここに私の最終的なテストコードが含まれています。私はこれを改善するコードを見たいと思います!あなたの質問でこの質問にリンクしてください。
# COPY TO CSV quick and dirty performance test
import io
import sys
start = time.time()
conn_str_copy= r'postgresql+psycopg2://' + user_id + r":" + pswd + r"@xxx.xxx.xxx.xxx:ppppp/my_database"
result = urlparse(conn_str_copy)
username = result.username
password = result.password
database = result.path[1:]
hostname = result.hostname
size = 2**30
buf = io.BytesIO()
# buf = io.StringIO()
engine = create_engine(conn_str_copy)
conn_copy= psycopg2.connect(
database=database, user=username, password=password, host=hostname)
cursor_copy = conn_copy.cursor()
sql_query = 'COPY ('+ my_sql_query + ') TO STDOUT WITH CSV HEADER'
cursor_copy.copy_expert(sql_query, buf, size)
print('time:', (time.time() - start)/60, 'minutes or ', time.time() - start, 'seconds')
tmp = buf.seek(0)
df = pd.read_csv(buf,engine='c', low_memory=False)
buf.close()
print('time:', (time.time() - start)/60, 'minutes or ', time.time() - start, 'seconds')
速度は、ポストグレースからデータをコピーして30秒未満でパンダのデータフレームにロードするのに約4分です。 copyコマンドはpsycopg2ドライバの機能であり、他のドライバでは動作しないことに注意してください。
(おそらく空のデータフレームを得るでしょう、それなしで試してください))'だからちょうど 'df = pd.read_csv(buf、engine = 'c')'確かではない、ちょうど推測する – piRSquared
@piRSquared:そうです。あなたはファイルハンドルを渡さなければなりません。そして、 'getvalue()'を渡すと、あなたはファイル名を渡しているとpandasが信じさせます。 –
しかしそれ以上のことがあります:バッファオブジェクトを "巻き戻す"必要があります。そうしないと動作しません。 –