【发布时间】:2016-11-07 07:52:14
【问题描述】:
我每天将大约 2 到 250 万条记录加载到 Postgres 数据库中。
然后我使用 pd.read_sql 读取这些数据以将其转换为数据框,然后我进行一些列操作和一些小的合并。我将这些修改后的数据保存为单独的表格供其他人使用。
当我执行 pd.to_sql 时,它需要很长时间。如果我保存一个 csv 文件并在 Postgres 中使用 COPY FROM,整个过程只需要几分钟,但服务器在单独的机器上,在那里传输文件很痛苦。
使用 psycopg2,看起来我可以使用 copy_expert 从批量复制中受益,但仍然使用 python。如果可能的话,我想避免编写实际的 csv 文件。我可以使用 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)
有人可以帮我提供示例代码吗?我还是更喜欢使用 pandas,在内存中这样做会很好。如果没有,我会写一个 csv 临时文件并这样做。
编辑-这是我的最终代码。每个日期(数百万行)只需要几百秒,而不是几个小时。
to_sql = """使用 CSV 标头从标准输入复制 %s"""
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)
【问题讨论】:
-
我不知道 psycopg2 但您可以尝试类似:
s_buf = io.StringIO(),df.to_csv(s_buf),它将您的 df 存储在类似文件的缓冲区中。然后可能是cur.copy_from(s_buf,...)而不是copy_expert。 -
强者成功了!不过,我仍然保持着复制专家。当我只使用普通的 pandas.to_sql 时,它只需要 100 秒,而 10000 秒。做出真实的回答,以便我接受
-
很高兴我能帮上忙。