我有一些“upsert”类型的问题......但是,我想把它扔在那里,因为它与我在 stackoverflow 上读到的任何内容都有点不同。
基本问题。
我正在从 mysql 迁移到 PostgreSQL 9.1.5(托管在 Heroku 上)。作为其中的一部分,我需要每天导入多个 CSV 文件。有些数据是销售信息,几乎可以保证是新的,需要插入。但是,数据的其他部分几乎可以保证是相同的。例如,csv 文件(注意复数)将包含 POS(销售点)信息。这很少改变(很可能只是通过添加)。然后是产品信息。大约有 10,000 种产品(绝大多数将保持不变,但可以同时进行添加和更新)。
最后一项(但很重要)是我要求能够为任何给定项目提供审计跟踪/信息。例如,如果我添加了一条新的 POS 记录,我需要能够将其追溯到它所在的文件。如果我更改了 UPC 代码或产品描述,那么我需要能够追溯它到更改来自的导入(和文件)。
我正在考虑的解决方案。
由于数据是通过 CSV 提供给我的,因此我正在考虑 COPY 将是最佳/最快方式的想法。文件中的数据结构并不完全是我在数据库中的结构(即最终目的地)。因此,我将它们复制到与 CSV 匹配的暂存模式中的表中(注意:每个数据源一个模式)。暂存模式中的表将有一个前插入行触发器。这些触发器可以决定如何处理数据(插入、更新或忽略)。
对于最有可能包含新数据的表,它会先尝试插入。如果记录已经存在,那么它将返回 NULL(并停止插入临时表)。对于很少更改的表,那么它将查询该表并查看是否找到记录。如果是,那么我需要一种方法来查看是否有任何字段被更改。(因为请记住,我需要证明记录是通过从文件 y 中导入 x 来修改的)我显然可以将代码样板化并测试每一列。但是,正在寻找比这更“雄辩”和更易于维护的东西。
在某种程度上,我正在做的是将导入系统与审计跟踪系统结合起来。因此,在研究审计跟踪时,我查看了以下wiki.postgresql.org文章。看起来 hstore 可能是获取更改的好方法(并且能够轻松忽略表中不重要的某些列 - 例如“last_modified”)
我大约有 90% 的把握这一切都会奏效......我已经创建了一些测试表等并使用它。
我的问题?
是一种更好、更易于维护的方式来完成从 10K 中查找可能需要更改数据库的 3 条记录的任务。我当然可以编写一个 python 脚本(或其他东西)来读取文件并试图弄清楚如何处理每条记录,但这感觉效率非常低,并且会导致大量往返。
最后的几件事:
- 我无法控制输入文件。如果他们只向我发送增量,我会很高兴,但他们没有,这完全超出了我的控制或影响。
- 他的系统正在增长,可能会添加新的数据源,这将大大增加正在处理的数据量(所以,我正在努力保持高效)
- 我知道这不是一个好的、简单的 SO 问题(例如“如何在 python 中对列表进行排序”),但我相信 SO 的一大优点是您可以提出棘手的问题,人们会分享他们对解决它的最好方法是。