Лучший способ массовой загрузки CSV-файла в таблицу PostgreSQL - PullRequest
0 голосов
/ 09 июля 2020

У меня есть CSV-файл, разделенный табуляцией, в D:\DataSet\business_names_202007/businessDataSet.csv с 600k записями (количество которых может увеличиться). Я хочу загрузить все данные в таблицу ниже postgresql.

PostgreSQL таблица:

PostgreSQL Structure

CSV file structure:

CSV File Structure

As you can see above structure, column count differs between CSV file and db ("transform_business" column extra in DB). while loading data we need to add this as well, the value for this column is given below.

"transform_business" column value in db is same as "BN_NAME" in the DataSet with following changes: Convert to UPPERCASE and all spaces should be removed between words

eg:

  • BN_NAME: Melbourne Collision Repair

  • transform_business: MELBOURNECOLLISIONREPAIR

  • Tool: Dbeaver

  • DB Schema: testDev

  • tablename: testdevtable

Ссылка на руководство

Временно сформированная выписка копта:

COPY testdevtable(register_name,bn_name,bn_status,transform_business) 
FROM 'D:\DataSet\business_names_202007/businessDataSet.csv' DELIMITER E’\t’ CSV HEADER;

Ответы [ 2 ]

0 голосов
/ 10 июля 2020

Возможно, вы упустили важную информацию: какая версия Postgres у вас установлена? Если у вас есть или вы можете обновить до версии 12 , вы можете переопределить свою таблицу так, чтобы столбец transform_business стал сгенерированным столбцом. Тогда, например:

create table table_name(
       id             bigint generated always as identity
     , register_name  text 
     , bn_name        text 
     , status         text 
     , transform_name text generated always as ( upper(replace(bn_name,' ',''))) stored
     ) ;

Если вам нужно сохранить текущие данные, вы можете:

alter table table_name  drop column transform_name; 
alter table table_name  add transform_name text generated always as ( upper(replace(bn_name,' ',''))) stored; 

Этот вариант будет довольно медленным, особенно если таблица большая, но она разовый процесс. Любая из этих опций даст вам «ограничение», что transform_name не может быть обновлено напрямую, но будет автоматически обновляться при обновлении bn_name.

Тогда ваша команда копирования просто загрузит register_name, bn_name и status.

0 голосов
/ 09 июля 2020

Если бы это было где я, я бы добавил триггер ON INSERT в бизнес-таблицу, который преобразует bn_name -> transform_business во время INSERT. Затем оставьте transform_business из COPY. Второй вариант - выполнить преобразование перед его загрузкой и добавить transform_business и новые данные в файл CSV.

Пример фрагмента кода SQL, который выполнит преобразование:

SELECT upper(replace('Melbourne Collision Repair Centre Mentone', ' ', ''));
                 upper                 
---------------------------------------
 MELBOURNECOLLISIONREPAIRCENTREMENTONE

Другой вариант - просто COPY (register_name, bn_name, bn_status) в базе данных (без триггера в таблице), а затем запустить:

UPDATE business SET transform_business = upper(replace(bn_name, ' ', ''));

Не уверен, что произойдет после этого, будь то значение transform_business будет вводиться с новыми данными или нет. Если пользователь / приложение не собирается вводить его, я думаю, вы вернулись к триггеру в бизнес-таблице, который запускает upper(replace(bn_name, ' ', '')).

...