使用ASCII 31字段分隔符作为Postgresql COPY分隔符

时间:2015-02-17 18:40:40

标签: postgresql escaping ascii delimiter control-characters

我们正在将Postgres 9.3中的数据导出到文本文件中以供Spark使用。

我们希望使用ASCII 31字段分隔符作为分隔符而不是\ t,以便我们不必担心转义问题。

我们可以在这样的shell脚本中执行此操作:

#!/bin/bash
DELIMITER=$'\x1F'
echo "copy ( select * from table limit 1) to STDOUT WITH DELIMITER '${DELIMITER}'" | (psql ...) > /tmp/ascii31

但是我们想知道,是否可以在" pure"中指定一个不可打印的字形作为分隔符。 postgres的?

编辑:我们尝试按http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html

使用postgres转义约定
warehouse=> copy ( select * from table limit 1) to STDOUT WITH DELIMITER '\x1f';

并收到

ERROR:  COPY delimiter must be a single one-byte character

3 个答案:

答案 0 :(得分:6)

尝试在您尝试用作分隔符的序列之前预先设置E.例如if (($time > 'five to the hour') && ($time < 'quarter past the hour')){ //do something } else {} 而不是E'\x1f'。没有E PostgreSQL会将'\x1f'读为四个单独的字符而不是十六进制转义序列,因此会显示错误消息。

有关详细信息,请参阅the PostgreSQL manual on "String Constants with C-style Escapes"

答案 1 :(得分:1)

从我的测试中,以下两项工作都是:

echo "copy (select 1 a, 2 b) to stdout with delimiter u&'\\001f'"| psql;

echo "copy (select 1 a, 2 b) to stdout with delimiter e'\\x1f'"| psql;

答案 2 :(得分:0)

我从Actian Matrix(Amazon Redshift的一个分支,这两个postgres的衍生物)中提取了一个小文件,使用这种符号表示ASCII字符代码30,“Record Separator”。

unload ('SELECT btrim(class_cd) as class_cd, btrim(class_desc) as class_desc
FROM transport.stg.us_fmcsa_carrier_classes')
to '/tmp/us_fmcsa_carrier_classes_mk4.txt'
delimiter as '\036' leader;

这是该文件在VI中的外观示例:

C^^Private Property
D^^Private Passenger Business
E^^Private Passenger Non-Business

然后我通过sftp将此文件移动到托管PostgreSQL 9.5的计算机上,并使用以下复制命令,这似乎运行良好:

copy fmcsa.carrier_classes
from '/tmp/us_fmcsa_carrier_classes_mk4.txt'
delimiter u&'\001E'; 

postgres的每个衍生物和postgres本身似乎更喜欢略有不同的符号。太糟糕了,我们没有单一的标准!