因此,我试图在内存不足的环境下,通过Pandas CSV dump功能,将大量数据从Postgres(在heroku上)存储到磁盘(整个表无法装入内存)。在
我原以为我可以简单地将它一次100行直接流到一个CSV文件中,代码如下:import psycopg2
import pandas as pd
from sqlalchemy import create_engine
connuri = "MY_DATABASE_CONNECTION_URL"
engine = create_engine(connuri, execution_options={'stream_results': True})
raw_engine = engine.raw_connection()
sql = "SELECT * FROM giant_table;"
firstchunk = True
for chunk in pd.read_sql_query(sql, raw_engine, chunksize=100):
if firstchunk:
chunk.to_csv("bigtable.csv", index=False)
firstchunk = False
else:
chunk.to_csv("bigtable.csv", mode="a", index=False, header=False)
但是,它仍然没有内存。在
从回溯来看,它似乎在正确地传输数据,但在尝试写入文件时内存不足,即:
^{pr2}$
我觉得这很奇怪。我本以为append模式只会在文件末尾插入一个游标,而不必将整个内容读入内存,然后将数据放入光标所在的位置。但可能需要读取整个文件才能做到这一点(?!)。在
我已经尝试将chunksize减小到10,并创建与engine.connect()而不是engine.raw_connection()的连接,以防问题是我根本没有真正从数据库流式传输数据。也没用。在
我还试着只打开一个文件句柄,然后逐块写入,如with open("attempted_download.csv", "w") as csv:
for chunk in pd.read_sql_query(sql, raw_engine, chunksize=10):
if firstchunk:
mystring = chunk.to_csv(index=False)
csv.write(mystring)
firstchunk = False
else:
mystring = chunk.to_csv(index=False, header=False)
csv.write(mystring)
但同样的记忆错误。我明显遗漏了什么?在
编辑
我还试图保存到一堆单独的文件中,即:def countermaker():
count = 0
def counter():
nonlocal count
count += 1
return "partial_csv{}.csv".format(count)
return counter
counter = countermaker()
for chunk in pd.read_sql_query(sql, raw_engine, chunksize=10):
if firstchunk:
chunk.to_csv(counter(), index=False)
firstchunk = False
else:
chunk.to_csv(counter(), index=False, header=False)
并得到了完全相同的错误,尽管它确实设法创建了578个文件。在