Правило Postgres, чтобы помочь с импортом CSV - PullRequest
1 голос
/ 20 сентября 2010

Мне нужно импортировать CSV-файл с десятками тысяч строк ежедневно в базу данных Postgres. Я ищу наиболее эффективный способ сделать это, поскольку каждая строка в CSV-файле может быть новой записью или существующей, которая должна быть обновлена, если она там есть. После многих поисков я наткнулся на решение, которое я использовал:

CREATE OR REPLACE RULE insert_on_duplicate_update_advertiser_campaign_keywords_table AS
  ON INSERT TO advertiser_campaign_keywords
  WHERE (new.phrase, new.match_type, new.advertiser_campaign_id) IN (
    SELECT phrase, match_type, advertiser_campaign_id
    FROM advertiser_campaign_keywords
    WHERE phrase = new.phrase AND match_type = new.match_type AND advertiser_campaign_id = new.advertiser_campaign_id AND state != 'deleted')
DO INSTEAD
  UPDATE advertiser_campaign_keywords
  SET bid_price_cpc = new.bid_price_cpc
  WHERE phrase = new.phrase AND match_type = new.match_type AND advertiser_campaign_id = new.advertiser_campaign_id;

Это самое близкое к мне рабочее решение, но оно не завершено. Он не работает на вставках, которые выглядят так:

INSERT INTO advertiser_campaign_keywords (phrase, bid_price_cpc, match_type, advertiser_campaign_id) VALUES 
('dollar', 1::text::money, 'Broad', 1450),
('two words', 1.2::text::money, 'Broad', 1450),
('two words', 1.0::text::money, 'Broad', 1450),
('three words exact', 2.5::text::money, 'Exact', 1450),
('four words broad match', 1.1::text::money, 'Exclusive', 1450),
('three words exact', 2.1::text::money, 'Exact', 1450);

Сообщение об ошибке:

duplicate key value violates unique constraint "unique_phrase_campaign_combo"

unique_phrase_campaign_combo выглядит так:

CONSTRAINT "unique_phrase_campaign_combo" UNIQUE ("phrase", "advertiser_campaign_id", "match_type", "deleted_at")

Удалено_, является нулевым, если запись не помечена как удаленная.

Кто-нибудь знает, как я могу решить эту проблему?

Спасибо

1 Ответ

4 голосов
/ 20 сентября 2010

Лучший способ сделать это - добавить промежуточный стол.Используйте копию, чтобы заполнить промежуточную таблицу.Затем используйте его для вставки и обновления.

UPDATE target_table t
  SET ...
FROM staging_table s
WHERE t.id = s.id

INSERT INTO target_table
SELECT * FROM staging_table s
WHERE s.id NOT EXISTS (
  SELECT id FROM target_table
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...