复制列顺序
COPY column order
我正在尝试将 COPY 与 HEADER 选项一起使用,但我在文件中的 header 行的顺序与数据库中指定的列顺序不同。
我的文件中是否需要列名顺序??
我的代码如下:
COPY table_name (
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
)
FROM 'file.csv'
WITH DELIMITER ',' CSV HEADER;
我的数据库 table 的顺序与 file.csv 不同,我想 select table 顺序并将数据从 csv 复制到 table .
您不能在 copy from
中发出 SQL 查询。您只能列出列。
如果 CSV 列按 b, a, c
顺序排列,则在 copy from
命令中列出:
copy target_table (b, a, c)
from file.csv
with (delimiter ',', format csv, header)
假设我们需要的列的顺序是我们从中复制结果的 table 之一,下一个合乎逻辑的步骤是通过 Bash 模拟子查询脚本。
psql schema_origin -c 'COPY table_origin TO stdout' | \
psql schema_destination -c \
"$(echo 'COPY table_destination (' \
$(psql schema_origin -t -c "select string_agg(column_name, ',') \
from information_schema.columns where table_name = 'table_origin'") \
') FROM stdin')"
StackExchange answer on fetching column names
Whosebug answer on fetching results as tuples
我想出了以下设置来使 COPY TO/FROM 即使对于非常复杂的 JSON 列也能成功:
COPY "your_schema_name.yor_table_name" (
SELECT string_agg(
quote_ident(column_name),
','
) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'yuour_table_name'
AND TABLE_SCHEMA = 'your_schema_name'
) FROM STDIN WITH CSV DELIMITER E'\t' QUOTE '\b' ESCAPE '\';
--here rows data
\.
最重要的部分:
- 明确过滤
information_schema.columns
和用户 table_schema
。否则,当一个 table 名称出现在多个模式中时,您可能会得到意外的列。
- 使用
quote_ident
确保如果有人使用 user
或 unique
等 Postgres 注册关键字对 table 列进行错误命名,您的命令不会崩溃。感谢 quote_ident
,您可以将它们用双引号括起来,这使它们可以安全导入。
我还发现了以下设置:
QUOTE '\b'
- 用退格键引用
DELIMITER E'\t'
- 制表符分隔符
ESCAPE '\'
- 并用反斜杠转义
用于使 COPY 来回最可靠也用于处理 sophisticated/nested JSON 列。
我正在尝试将 COPY 与 HEADER 选项一起使用,但我在文件中的 header 行的顺序与数据库中指定的列顺序不同。 我的文件中是否需要列名顺序??
我的代码如下:
COPY table_name (
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
)
FROM 'file.csv'
WITH DELIMITER ',' CSV HEADER;
我的数据库 table 的顺序与 file.csv 不同,我想 select table 顺序并将数据从 csv 复制到 table .
您不能在 copy from
中发出 SQL 查询。您只能列出列。
如果 CSV 列按 b, a, c
顺序排列,则在 copy from
命令中列出:
copy target_table (b, a, c)
from file.csv
with (delimiter ',', format csv, header)
假设我们需要的列的顺序是我们从中复制结果的 table 之一,下一个合乎逻辑的步骤是通过 Bash 模拟子查询脚本。
psql schema_origin -c 'COPY table_origin TO stdout' | \
psql schema_destination -c \
"$(echo 'COPY table_destination (' \
$(psql schema_origin -t -c "select string_agg(column_name, ',') \
from information_schema.columns where table_name = 'table_origin'") \
') FROM stdin')"
StackExchange answer on fetching column names
Whosebug answer on fetching results as tuples
我想出了以下设置来使 COPY TO/FROM 即使对于非常复杂的 JSON 列也能成功:
COPY "your_schema_name.yor_table_name" (
SELECT string_agg(
quote_ident(column_name),
','
) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'yuour_table_name'
AND TABLE_SCHEMA = 'your_schema_name'
) FROM STDIN WITH CSV DELIMITER E'\t' QUOTE '\b' ESCAPE '\';
--here rows data
\.
最重要的部分:
- 明确过滤
information_schema.columns
和用户table_schema
。否则,当一个 table 名称出现在多个模式中时,您可能会得到意外的列。 - 使用
quote_ident
确保如果有人使用user
或unique
等 Postgres 注册关键字对 table 列进行错误命名,您的命令不会崩溃。感谢quote_ident
,您可以将它们用双引号括起来,这使它们可以安全导入。 我还发现了以下设置:
QUOTE '\b'
- 用退格键引用DELIMITER E'\t'
- 制表符分隔符ESCAPE '\'
- 并用反斜杠转义
用于使 COPY 来回最可靠也用于处理 sophisticated/nested JSON 列。