我每天在Postgres数据库中加载大约2到250万条记录。
然后我用pd.read_sql读取这些数据,将其转换为数据帧,然后进行一些列操作和一些小的合并。我将此修改后的数据另存为一个单独的表供其他人使用。
当我做pd.to_sql时,它需要永远。如果我保存一个csv文件并在Postgres中使用COPY FROM,整个过程只需要几分钟,但服务器在一台单独的机器上,在那里传输文件很痛苦。
使用psycopg2,看起来我可以使用copy_expert从批量复制中受益,但仍然使用python。我希望,如果可能的话,避免编写实际的csv文件。我可以在内存中使用pandas数据帧吗?
以下是我的pandas代码的示例。我想添加copy_expert或其他东西,以便尽可能快地保存这些数据。
for date in required_date_range:
df = pd.read_sql(sql=query, con=pg_engine, params={'x' : date})
...
do stuff to the columns
...
df.to_sql('table_name', pg_engine, index=False, if_exists='append', dtype=final_table_dtypes)
有人可以通过示例代码帮助我吗?我更喜欢使用熊猫,在内存中做它会很好。如果没有,我只会编写一个csv临时文件并以这种方式执行。
编辑 - 这是我的最终代码。每个日期(数百万行)只需要几百秒而不是几个小时。
to_sql =“”“COPY%s FROM STDIN WITH CSV HEADER”“”
def process_file(conn, table_name, file_object):
fake_conn = cms_dtypes.pg_engine.raw_connection()
fake_cur = fake_conn.cursor()
fake_cur.copy_expert(sql=to_sql % table_name, file=file_object)
fake_conn.commit()
fake_cur.close()
#after doing stuff to the dataframe
s_buf = io.StringIO()
df.to_csv(s_buf)
process_file(cms_dtypes.pg_engine, 'fact_cms_employee', s_buf)
答案 0 :(得分:18)
Python模块io
(docs)具有类似文件对象的必要工具。
import io
# text buffer
s_buf = io.StringIO()
# saving a data frame to a buffer (same as with a regular file):
df.to_csv(s_buf)
修改强> (我忘了)为了之后从缓冲区读取,它的位置应该设置为开头:
s_buf.seek(0)
我不熟悉psycopg2
,但根据docs,可以使用copy_expert
和copy_from
,例如:
cur.copy_from(s_buf, table)
(对于Python 2,请参阅StringIO。)
答案 1 :(得分:4)
我在从ptrj实现解决方案时遇到了问题。
我认为这个问题源于大熊猫将缓冲区的位置设置到最后。
见如下:
<logger message="print substring of value: #[json:color] level="INFO" doc:name="Logger"/>
请注意,pos是12.我必须将pos设置为0,以便后续的copy_from命令工作
<logger message="print substring of value: #[json:color].substring(0,1) level="INFO" doc:name="Logger"/>