У меня есть вопрос типа "upsert"... но я хочу высказать его, потому что он немного отличается от всего, что я читал в stackoverflow.
Основная проблема.
Я работаю над переходом с mysql на PostgreSQL 9.1.5 (размещенный на Heroku). В связи с этим мне нужно каждый день импортировать несколько CSV-файлов. Некоторые данные являются информацией о продажах и почти гарантированно являются новыми и должны быть вставлены. Но другие части данных почти гарантированно будут одинаковыми. Например, файлы csv (обратите внимание на множественное число) будут содержать информацию о POS (точке продажи). Это редко меняется (и, скорее всего, только через дополнения). Затем идет информация о продукте. Товаров около 10 000 (подавляющее большинство останется без изменений, но возможны как дополнения, так и обновления).
Последний элемент (но важный) заключается в том, что у меня есть требование предоставить контрольный журнал/информацию для любого данного элемента. Например, если я добавляю новую запись POS, мне нужно иметь возможность отследить ее до файла, в котором она была найдена. Если я изменяю код UPC или описание продукта, мне нужно иметь возможность отследить ее обратно. к импорту (и файлу), откуда пришло изменение.
Решение, которое я обдумываю.
Поскольку данные предоставляются мне через CSV, я работаю над идеей, что COPY будет лучшим/самым быстрым способом. Структура данных в файлах не совсем та, что у меня в базе данных (т.е. конечный пункт назначения). Итак, я копирую их в таблицы промежуточной схемы, которые соответствуют CSV (примечание: одна схема для каждого источника данных). Таблицы в промежуточных схемах будут иметь триггеры перед вставкой строки. Эти триггеры могут решить, что делать с данными (вставить, обновить или игнорировать).
Для таблиц, которые, скорее всего, будут содержать новые данные, он попытается вставить их первыми. Если запись уже есть, то она вернет NULL (и остановит вставку в промежуточную таблицу). Для таблиц, которые редко изменяются, он будет запрашивать таблицу и проверять, найдена ли запись. Если это так, то мне нужен способ увидеть, изменилось ли какое-либо из полей. (потому что помните, мне нужно показать, что запись была изменена путем импорта x из файла y). Я, очевидно, могу просто создать код и протестировать каждый столбец. Но искал что-то более «красноречивое» и более удобное в обслуживании.
В каком-то смысле я комбинирую систему импорта с системой контрольного журнала. Итак, изучая журналы аудита, я просмотрел следующую статью wiki.postgresql.org. Кажется, что hstore может быть хорошим способом получения изменений (и возможностью легко игнорировать некоторые столбцы в таблице, которые не важны, например, «last_modified»)
Я примерно на 90% уверен, что все это будет работать... Я создал несколько тестовых таблиц и т. д. и поэкспериментировал с ними.
Мой вопрос?
Это лучший, более удобный способ выполнения этой задачи по поиску, возможно, 3 записей из 10 КБ, которые требуют изменения в базе данных. Я, конечно, мог бы написать скрипт на Python (или что-то еще), который читает файл и пытается выяснить, что делать с каждой записью, но это кажется ужасно неэффективным и приведет к большому количеству циклов.
Несколько заключительных вещей:
- У меня нет контроля над входными файлами. Я был бы рад, если бы они прислали мне только дельты, но они этого не делают, и это полностью вне моего контроля или влияния.
- Система растет, и, вероятно, будут добавлены новые источники данных, которые значительно увеличат объем обрабатываемых данных (поэтому я стараюсь поддерживать эффективность)
- Я знаю, что это нехороший, простой вопрос SO (например, «как отсортировать список в python»), но я считаю, что одна из замечательных особенностей SO заключается в том, что вы можете задавать трудные вопросы, и люди будут делиться своими мыслями о том, как они думают лучший способ решить это.