3

我转储我的表数据:

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

如您所见,这些字段optionperiodic翻转。

Postgres 文档说

标题

指定文件包含带有文件中每一列名称的标题行。输出时,第一行包含表中的列名,输入时,第一行被忽略。仅当使用 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;"  ||:
4

2 回答 2

1

您可以在以下位置指定目标列名称COPY FROM

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

(我翻转optionperiodic。)

另外:SELECT * FROM tbl 确实以确定的顺序返回列 - 如pg_attribute.attnum. 因此,在转储和恢复之间,您的数据库中发生了一些变化。

于 2018-05-10T15:52:16.783 回答
0

作为解决方法,我使用: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;"  ||:
于 2018-07-08T08:20:16.297 回答