来自/ import的Postgres CSV COPY不符合CSV标题

时间:2015-10-22 00:15:22

标签: postgresql csv

我尝试将CS​​V中的数据导入到表格中。问题是,即使使用CSV HEADER,也会根据列索引导入CSV,而不是在该列的标题上导入。

CREATE TABLE denominations (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

CREATE TABLE churches (
  id SERIAL PRIMARY KEY,
  -- NOT relevant here
  address_id INTEGER REFERENCES addresses,
  denomination_id INTEGER NOT NULL REFERENCES denominations,
  name VARCHAR(100) NOT NULL
);

我的CSV看起来像:

id,name
1,Southern Baptist Convention
2,Nondenominational
3,Catholic
4,Presbyterian


id,denomination_id,name,address_id
1,1,Saddleback Church,
2,4,First Presbyterian Church,
3,3,St. Elizabeth's Church,
4,3,St Monica Catholic Community,
5,2,Modern Day Saints Church,
6,4,Second Presbyterian Church,

我的COPY命令在bash中看起来像这样:

psql -d vacation -c "COPY denominations FROM '$PWD/data/Data - Denominations.csv' WITH DELIMITER ',' CSV HEADER;"
psql -d vacation -c "COPY churches FROM '$PWD/data/Data - Churches.csv' WITH DELIMITER ',' CSV HEADER;"

我得到的错误是:

ERROR:  invalid input syntax for integer: "Saddleback Church"
CONTEXT:  COPY churches, line 2, column denomination_id: "Saddleback Church"

目前,我要重新安排CSV中的列,但不应该这样做吗?

3 个答案:

答案 0 :(得分:10)

默认情况下,COPY命令按照表中列的默认顺序从CSV文件中复制列。 HEADER选项on input is ignored,它基本上只通知后端忽略输入的第一行。如果CSV中列的顺序与表中列的顺序不匹配,则可以显式指定列顺序以匹配CSV文件的布局:

COPY churches (id,denomination_id,name,address_id)
FROM '$PWD/data/Data - Churches.csv'
WITH DELIMITER ',' CSV HEADER;

答案 1 :(得分:0)

只需在公认的答案下回答Jonathan的评论-如果您想从CSV中“尊重”列顺序加载数据(我有一些转储具有不同的架构迁移历史,或者我想导入缺少的列)

如果要使用CSV标头将其导入Bash中,请执行以下操作: (我的表的名称为alarms

#!/bin/bash

if [ -z "$1" ] ; then
    echo "Usage: $0 <alarms_dump_file.csv>"
    exit
fi

columns=$(head -n1 $1)
echo "Using columns:"
if ! echo $columns | grep '^id,' ; then
    echo "Missing id in header. No header present? See below:"
    echo $columns
    exit
fi

sudo -u postgres psql YOUR_DATABASE <<EOF
\copy alarms ( $columns ) FROM '$1' DELIMITER ',' CSV HEADER;
EOF

答案 2 :(得分:0)

这是一个使用csv标题行导入用户的单行示例:

echo "\copy users ($(head -1 users.csv)) FROM 'users.csv' DELIMITER ',' CSV HEADER" | psql

或使用gzip:

echo "\copy users ($(gzip -dc users.csv.gz | head -1)) FROM PROGRAM 'gzip -dc users.csv.gz' DELIMITER ',' CSV HEADER" | psql