对于用python将大型csv文件处理成多个postgresql表,在线上也有一些类似的问题。然而,似乎没有一个能解决关于优化数据库读/写和系统内存/处理的几个问题。你知道吗
假设我有一行产品数据,如下所示:
名称、sku、日期时间、十进制、十进制、十进制、十进制、十进制、十进制
如果名称和sku存储在一个表(父表)中,则每个十进制字段都存储在一个子EAV表中,该子EAV表基本上包含十进制、父表\ id和日期时间。你知道吗
假设我在一个csv文件中有20000行这样的行,所以我最终将它们分块。现在,我从2000行中取出一大块,一行一行地循环。每次迭代都检查产品是否存在,如果不存在,则创建产品,检索父表的\u id。然后,我有一个为子表生成的带有十进制值的insert语句的大列表。如果用户选择仅覆盖未修改的十进制值,则在添加到插入列表之前,还将检查每个十进制值是否已修改。你知道吗
在这个例子中,如果我遇到最坏的情况,我最终会执行160000次数据库读取和10-20010次写入。我还将在内存中的一个列表中为每个块存储多达12000条insert语句(但是,这将只有一个列表,所以这部分没有那么糟糕)。你知道吗
我的主要问题是:
一些子问题是:
一个有趣的问题,但很难准确回答,因为有很多 定义可能适用或不适用的最佳解决方案的变量。你知道吗
以下是一种基于以下假设的方法-
product_id
上有一个唯一的约束,并且attr_name
这个过程可以归结为-
接近-
所有这些背景,考虑到一个类似的问题,这里是我将采取的方法。你知道吗
insert into tmp_eav (sku, attr_name, attr_value) values (%s, %s), (%s, %s)...
。你知道吗psycopg2
有一个自定义方法来为您执行此操作:http://initd.org/psycopg/docs/extras.html#psycopg2.extras.execute_valuesinsert into product (name, sku) select name, sku from tmp_product on conflict (sku) do nothing
的语句,从tmp表中选择以向上插入最终表do nothing
更改为do update set col = excluded.col
。excluded
是冲突的输入行替代方法-
cursor.copy_from
方法,将csv作为文件对象传入)。 这将比用Python编写的任何东西都要快例如:
此解决方案涉及您感兴趣的几个方面:
一个关于结束的小建议-
相关问题 更多 >
编程相关推荐