Как заставить Postgres использовать порядок столбцов из CSV при сбросе / восстановлении данных? - PullRequest
0 голосов
/ 10 мая 2018

Я сбрасываю свои данные таблицы:

COPY( SELECT * FROM tariff_details ) TO STDOUT WITH( FORMAT CSV, HEADER )

Данные:

id,tariff_id,name,price,option,periodic,value,sorder
17,1,Setup fee,5.000000000000000000,,f,,0

Когда я восстанавливаю данные:

COPY tariff_details FROM STDIN WITH( FORMAT CSV, HEADER )

Я получаю ошибку:

ERROR:  null value in column "periodic" violates not-null constraint
DETAIL:  Failing row contains (17, 1, Setup fee, 5.000000000000000000, null, f, null, 0).
CONTEXT:  COPY tariff_details, line 2: "17,1,Setup fee,5.000000000000000000,,f,,0"

Таблица в базе данных определена следующим образом:

  Column   |         Type          |                          Modifiers                          
-----------+-----------------------+-------------------------------------------------------------
 id        | integer               | not null default nextval('tariff_details_id_seq'::regclass)
 tariff_id | integer               | not null
 name      | character varying(64) | not null
 price     | tmoney                | not null
 periodic  | boolean               | not null default false
 option    | character varying(16) | 
 value     | text                  | 
 sorder    | integer               | not null default 0

Как видите, поля option и periodic перевернуты.

В документации Postgres написано :

HEADER

Указывает, что файл содержит строку заголовка с именами каждого столбца в файле.При выводе первая строка содержит имена столбцов из таблицы, а при вводе первая строка игнорируется .Эта опция разрешена только при использовании формата CSV.

Как указать postgres использовать порядок столбцов из файла CSV?Возможно ли это?

UPD

В качестве обходного пути я использую: line=$$(head -n 1 ${APP_ROOT}/db/${TABLE}.dump.csv)

dbrestoretable: export PGPASSWORD =  ${DB_PASS}
dbrestoretable:
    line=$$(head -n 1 ${APP_ROOT}/db/${TABLE}.dump.csv)
    @cat ${APP_ROOT}/db/${TABLE}.dump.csv | \
        psql -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} ${DB_NAME} -c \
            "BEGIN;COPY ${TABLE}($$line) FROM STDIN WITH( FORMAT CSV, HEADER );COMMIT;"  ||:

Ответы [ 2 ]

0 голосов
/ 08 июля 2018

В качестве обходного пути я использую: columns=$$(head -n 1 ${APP_ROOT}/db/${TABLE}.dump.csv)

dbrestoretable: export PGPASSWORD =  ${DB_PASS}
dbrestoretable:
    columns=$$(head -n 1 ${APP_ROOT}/db/${TABLE}.dump.csv)
    @cat ${APP_ROOT}/db/${TABLE}.dump.csv | \
        psql -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} ${DB_NAME} -c \
            "BEGIN;COPY ${TABLE}($$columns) FROM STDIN WITH( FORMAT CSV, HEADER );COMMIT;"  ||:
0 голосов
/ 10 мая 2018

Вы можете просто указать target имена столбцов в COPY FROM:

COPY tariff_details(id,tariff_id,name,option,price,periodic,value,sorder)
FROM STDIN WITH (FORMAT CSV, HEADER);

(я перевернул option и periodic.)

В стороне: SELECT * FROM tbl возвращает столбцы в детерминированном порядке - как определено в pg_attribute.attnum. Так что что-то изменилось в вашей БД между dump и restore.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...