POT*_*NZA 48 csv postgresql etl copy
我有一个包含10列的CSV文件.创建一个包含4列的PostgreSQL表后,我想将10列中的一些列复制到表中.
我的CSV表的列如下:
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
我的PostgreSQL表的列应该是这样的:
x2 x5 x7 x10
Clo*_*eto 65
创建一个包含输入文件中所有列的临时表
create temporary table t (x1 integer, ... , x10 text)
从文件复制到其中:
copy t (x1, ... , x10)
from '/path/to/my_file'
with (format csv)
现在从temp插入到权威表中:
insert into my_table (x2, x5, x7, x10)
select x2, x5, x7, x10
from t
放下它:
drop table t
使用file_fdw扩展名.作为超级用户:
create extension file_fdw;
create server my_csv foreign data wrapper file_fdw;
create foreign table my_csv (
    x1 integer,
    x2 text,
    x3 text
) server my_csv
options (filename '/tmp/my_csv.csv', format 'csv' )
;
将表的权限授予将读取它的用户:
grant select on table my_csv to the_read_user;
然后在必要时直接从csv文件中读取,就好像它是一个表:
insert into my_table (x2)
select x2
from my_csv
where x1 = 2
Jul*_*ien 27
您可以使用COPY命令提供要填充的列.像这样:
\copy your_table (x2,x5,x7,x10) FROM '/path/to/your-file.csv' DELIMITER ',' CSV;
这里的文档的COPY命令.
Jam*_*own 11
刚刚到达这里寻求解决方案只加载一个列的子集,但显然这是不可能的.因此,使用awk(或cut)将所需列提取到新文件new_file:
$ awk '{print $2, $5, $7, $10}' file > new_file
并加载new_file.您可以将输出直接输出到psql:
$ cut -d \  -f 2,5,7,10 file | 
  psql -h host -U user -c "COPY table(col1,col2,col3,col4) FROM STDIN DELIMITER ' '" database
小智 8
您可以进一步采纳詹姆斯·布朗的建议并执行以下操作:
$ awk -F ',' '{print $2","$5","$7","$10}' file | psql -d db -c "\copy MyTable from STDIN csv header"
正如其他答案所指出的那样,可以指定要复制到PG表中的列。但是,如果没有选择在CSV中引用列名的选项,那么除了加载到表中各列具有不同顺序的表之外,它几乎没有其他用途。
幸运的是,从Postgres 9.3开始,不仅可以从文件或标准输入中复制列,还可以使用PROGRAM从shell命令复制列:
程序
要执行的命令。在COPY FROM中,从命令的标准输出中读取输入,而在COPY TO中,将输出写入命令的标准输入中。
请注意,该命令是由Shell调用的,因此,如果您需要将任何来自不受信任来源的参数传递给shell命令,则必须小心删除或转义可能对shell有意义的任何特殊字符。出于安全原因,最好使用固定的命令字符串,或者至少避免在其中传递任何用户输入。
这是我们如此渴望的功能所需要的缺少的部分。例如,我们可以结合使用此选项cut(在基于UNIX的系统中)按顺序选择某些列:
COPY my_table (x2, x5, x7, x10) FROM PROGRAM 'cut -d "," -f 2,5,7,10 /path/to/file.csv' WITH (FORMAT CSV, HEADER)
但是,cut在处理CSV时有一些限制:它不能适当地处理其中带有逗号(或其他分隔符)的字符串,并且不允许按名称选择列。
还有其他几种更擅长处理CSV文件的开源命令行工具,例如csvkit或miller。这是一个miller用于按名称选择列的示例:
COPY my_table (x2, x5, x7, x10) FROM PROGRAM 'mlr --csv  lf cut -f x2,x5,x7,x10 /path/to/file.csv' WITH (FORMAT CSV, HEADER)
| 归档时间: | 
 | 
| 查看次数: | 59451 次 | 
| 最近记录: |