Используйте COPY, чтобы прочитать csv в базу данных, добавляя постоянные столбцы - PullRequest
1 голос
/ 28 февраля 2020

У меня есть серия CSV-файлов в формате:

"Alice","Bob","A",123.46,"4"
"Charlie","Dana","B",987.6543,"9"
...

Я хочу создать такую ​​таблицу:

id   file_id  mch    c1         c2      c3   c4        c5
---  -------  -----  ---------  ------  ---  --------  ---
1    462      FALSE  'Alice'    'Bob'   'A'  123.46    '4'
2    462      FALSE  'Charlie'  'Dana'  'B'  987.6543  '9'
...  462      FALSE  ...        ...     ...  ...       ...
...  ...      ...    ...        ...     ...  ...       ...

, где

  • id является первичным ключом, произвольным и должен автоматически генерироваться в порядке вставки. Это указано как таковое.
  • file_id является константой для файла, который я хочу вставить в эту таблицу, хотя варьируется между файлами. Это известно до того, как я попытаюсь массово добавить файл.
  • mch всегда ложно, во время вставки
  • c1 до c5 являются общими c заголовками столбцов , с заранее известными типами.

В настоящее время я использую следующую команду SQL для массовой вставки каждого из моих файлов CSV:

COPY pos(c1,c2,c3,c4,c5) 
FROM 'C:/Users/.../filename.csv' 
WITH (FORMAT CSV, HEADER FALSE, ENCODING 'UTF8')

, которая работает для заполнения идентификатор первичного ключа. Это создает таблицу без столбцов file_id или mch.

Но я не могу понять, как правильно заполнить два других столбца (file_id и mch) внутри одного и того же оператора, не выполняя совсем другой оператор UPDATE.

1 Ответ

1 голос
/ 29 февраля 2020

Принимая это определение таблицы:

CREATE TABLE pos (
  id        serial PRIMARY KEY
, file_id   int
, mch       bool
, c1        text
, c2        text
, c3        text
, c4        numeric
, c5        text
);

Руководство по COPY:

Столбцы таблицы не указаны в списке столбцов COPY FROM получит значения по умолчанию.

Вы уже видите этот эффект для id, где назначено значение по умолчанию. Оставшиеся столбцы для работы: mch и file_id:

  • mch всегда ложно, на момент вставки

Make это так, навсегда:

ALTER TABLE pos ALTER mc SET DEFAULT false;

Необходимые привилегии : Вы должны владеть столом или быть суперпользователем, чтобы использовать ALTER TABLE.

  • file_id является константой для файла, который я хочу вставить в эту таблицу, хотя варьируется между файлами. Это известно до того, как я попытаюсь массово добавить файл.

Установить столбец по умолчанию перед запуском COPY. Вы можете сделать это внутри транзакции, если не хотите, чтобы другие вставки имели такую ​​же настройку по умолчанию. (Команды DDL полностью транзакционны в Postgres.) Но это блокирует таблицу для остальной части транзакции (ACCESS EXCLUSIVE lock ).

Или вы запускаете отдельную команду (в свою собственную транзакцию) до COPY. Тогда по умолчанию, возможно, действует для одновременных транзакций. Но вам нужна только очень короткая блокировка таблицы.

-- BEGIN;  -- optional transaction wrapper
ALTER TABLE pos ALTER file_id SET DEFAULT 462;

COPY pos(c1,c2,c3,c4,c5) 
FROM 'C:/Users/.../filename.csv' 
WITH (FORMAT CSV, HEADER FALSE, ENCODING 'UTF8');  -- unchanged!

-- ALTER TABLE pos ALTER file_id DROP DEFAULT;  -- optional
-- COMMIT;  -- if you BEGIN; also COMMIT;

Вы можете или не можете сбросить значение столбца по умолчанию для file_id после COPY. Если вы собираетесь запустить следующий COPY с новым значением по умолчанию сразу после этого, вы можете просто установить это новое значение по умолчанию ...

Или вы можете захотеть записать старый столбец по умолчанию и сбросить его. См .:

...