如何将 PostgreSQL COPY 转储中的日期时间值重新格式化为 TSV 以进行 ClickHouse 导入?

How to reformat datetime value in PostgreSQL COPY dump to TSV for ClickHouse import?

(我正在尝试将 7m 行 table 从 PostgreSQL 复制到 ClickHouse)

我是 运行 Docker 中的 Postgres,并复制到制表符分隔的变量转储文件:

docker exec -it db psql -U db_user db_name  -c "COPY table_name ( datetime, value1, value2) TO STDOUT" > outfile.tsv

但是日期时间列输出是'2021-12-21 09:01:44+00'

不幸的是我的 ClickHouse 导入 ...

cat outfile.tsv | curl 'http://localhost:8123/?query=INSERT%20INTO%20my_ch_db.my_table%20FORMAT%20TSV' --data-binary @-

... 需要格式为 2021-12-21 09:01:44

的日期时间列

我可以使用 SELECT 和 TO_CHAR

从 Postgres 获得所需的格式
SELECT TO_CHAR(datetime,'YYYY-MM-DD HH24:MI::SS') FROM my_table 

但无法找到一种方法来组合 COPY 和 TO_CHAR 以获得我的 ClickHouse TSV 导入所需的格式。

如果我尝试这样做,我会收到语法错误:

docker exec -it db psql -U db_user db_name  -c "COPY table_name ( TO_CHAR(datetime,'YYYY-MM-DD HH24:MI::SS'), value1, value2) TO STDOUT" > outfile.tsv

ERROR:  syntax error at or near "("
LINE 1: COPY my_table (TO_CHAR(datetime, 'YYYY-MM-DD H...

回答: 从 uysizfoz 将设置添加到 URL,如下所示:

cat outfile.tsv | curl 'http://localhost:8123/?date_time_input_format=best_effort&query=INSERT%20INTO%20my_ch_db.my_table%20FORMAT%20TSV' --data-binary @-

更多 ClickHouse 设置信息是 here

最后我也需要更改 BOOL col,所以写了一个小 Python 脚本如下(真的应该首先这样做)

import sys

infile = open(sys.argv[1],'r')
outfile = open(sys.argv[2],'a')

line_arr = []
while True:
    next_line = infile.readline()
    if not next_line:
        break;
    line_arr = next_line.split('\t')
    if line_arr[7] == 't':
        line_arr[7] = '1'
    else:
        line_arr[7] = '0'
    converted_list = [str(element) for element in line_arr]
    joined_string = "\t".join(converted_list)
    outfile.write(joined_string)
infile.close()
outfile.close()

答案 2: 使用 here.

中描述的 CSV 导入方法

添加设置date_time_input_format=best_effort