我正在尝试从Google存储设备读取一堆大的csv文件(多个文件)。我使用 Dask 分发库进行并行计算,但是我在这里面临的问题是,尽管我提到了 blocksize(100mb),但我不确定如何逐分区读取分区,并将其保存到我的 postgres 数据库中,这样我就不会过载内存。
from dask.distributed import Client
from dask.diagnostics import ProgressBar
client = Client(processes=False)
import dask.dataframe as dd
def read_csv_gcs():
with ProgressBar():
df = dd.read_csv('gs://mybucket/renish/*.csv', blocksize=100e6)
pd = df.compute(scheduler='threads')
return pd
def write_df_to_db(df):
try:
from sqlalchemy import create_engine
engine = create_engine('postgresql://usr:pass@localhost:5432/sampledb')
df.to_sql('sampletable', engine, if_exists='replace',index=False)
except Exception as e:
print(e)
pass
pd = read_csv_gcs()
write_df_to_db(pd)
上面的代码是我的基本实现,但是正如我所说,我想分块读取它并更新数据库。像
df = dd.read_csv('gs://mybucket/renish/*.csv', blocksize=100e6)
for chunk in df:
write_it_to_db(chunk)
是否可以在 Dask中完成它??还是应该选择pandas的块大小并进行迭代,然后将其保存到DB中(但是我在这里错过了并行计算)?
有人可以照亮吗?
答案 0 :(得分:1)
此行
df.compute(scheduler='threads')
说:在工作线程中以块的形式加载数据,并将它们全部串联到单个内存数据帧df
中。这不是您想要的。您想在块插入时插入它们,然后将其从内存中删除。
您可能想使用map_partitions
df = dd.read_csv('gs://mybucket/renish/*.csv', blocksize=100e6)
df.map_partitions(write_it_to_db).compute()
或使用df.to_delayed()
。
请注意,根据您的SQL驱动程序,您可能无法以这种方式获取并行性,否则,pandas的iter-chunk方法将同样有效。