Postgresql csv导入期间,Postgres中的最大列数为1600

Postgresql csv导入期间,Postgres中的最大列数为1600,postgresql,csv,import,Postgresql,Csv,Import,我正在尝试将一个巨大的csv文件(近10000列)导入postgres数据库。通常要导入文件,我会将其复制到临时表中,然后使用临时表将所有内容放在正确的位置。但是,postgres的最大列数为1600,因此csv不会导入。我无法控制csv的大小或其格式,因此我需要使用它 有没有办法增加临时表的此值,或者使用copy命令解析为多个临时表?如果您有任何建议,我也可以使用其他方式导入文件 有什么建议吗?我当前正在使用Copy命令导入csv: COPY INTAKE FROM 'file locatio

我正在尝试将一个巨大的csv文件(近10000列)导入postgres数据库。通常要导入文件,我会将其复制到临时表中,然后使用临时表将所有内容放在正确的位置。但是,postgres的最大列数为1600,因此csv不会导入。我无法控制csv的大小或其格式,因此我需要使用它

有没有办法增加临时表的此值,或者使用copy命令解析为多个临时表?如果您有任何建议,我也可以使用其他方式导入文件

有什么建议吗?我当前正在使用Copy命令导入csv:

COPY INTAKE
FROM 'file location'
CSV HEADER;

谢谢你的帮助

将其全部作为一列导入,如下所述:

一旦有了这些,您就可以组合一个查询,该查询将生成SQL,以您想要的方式提取您想要的字段。一个小示例,有5列,最大表大小为2列(IRL,您希望将此代码块中的每个表的最大列数(如1kish),因此创建10个表,而不是5000个表)

生成CREATE TABLE语句,以便将其拆分为实际列(如果值中有逗号,这将中断;我不打算在SQL中实现完整的CSV解析器:)


进一步的改进,可能是为了明智地使用第1行作为列名,或者总是包含一些对连接表有用的列,留给读者作为练习。

要将其导入数据库,请按所述将其作为单列表导入。在这一点上,您至少可以使用字符串到数组等来操作它。您可能需要编写一些动态SQL来生成一些大的CREATE TABLE语句,这些语句的表达式有
string到数组(d,,')[1..1600]作为col[1..1600]
,然后是1601-3200,等等。具体的外观取决于您希望数据最终的外观。(但它不能“作为10000列表”-无法更改该值,它取决于编译时常量。)@AdamKG不幸的是,我不认为这会起作用,因为csv中也有超过1600行,所以只要将表格侧向旋转,仍然会达到1600个限制。你误解了-这不会转置行/列,它只会使pg将csv中的每一行视为一行。CSV中的行数与行数相同,每行只有一列。感谢您的详细解释,我将尝试一下!
$ cat /tmp/fivewide.csv
c1,c2,c3,c4,c5
r1c1,r1c2,r1c3,r1c4,r1c5
r2c1,r2c2,r2c3,r2c4,r2c5
$ psql -X testdb
psql (12.3 (Debian 12.3-1), server 10.5 (Debian 10.5-1+build4))
Type "help" for help.

testdb=# create table my_import_table(data text);
CREATE TABLE
testdb=# \copy my_import_table from /tmp/fivewide.csv csv delimiter e'\x01' quote e'\x02'
COPY 3
testdb=# select * from my_import_table;
           data           
--------------------------
 c1,c2,c3,c4,c5
 r1c1,r1c2,r1c3,r1c4,r1c5
 r2c1,r2c2,r2c3,r2c4,r2c5
(3 rows)
testdb=# with
settings as (select 2 as max_cols_per_table, 'my_import_table' as import_table, 'data' as column_name),
computed_settings1 as (select array_length(string_to_array(d, ','), 1) as num_cols from t limit 1),
computed_settings2 as (select (ceil((select num_cols::float from computed_settings1) / (select max_cols_per_table from settings)))::integer as num_tables),
columns_exprs as (select i, '(string_to_array('||(select column_name from settings)||$$, ','))[$$||i||'] AS col'||i as cexpr from generate_series(1, (select num_cols from computed_settings1)) as i),
column_exprs_by_table as (select t, cexpr from generate_series(1, (select num_tables from computed_settings2)) as t join columns_exprs ce
on i>((t-1)*(select max_cols_per_table from settings))
AND i<=(t*(select max_cols_per_table from settings))
),
create_table_stmts as (select 'create table t_'||t||' AS SELECT '||string_agg(cexpr, ', ')||' FROM '||(select import_table from settings)||';' from column_exprs_by_table group by t)
select * from create_table_stmts;
                                                             ?column?                                                              
-----------------------------------------------------------------------------------------------------------------------------------
 create table t_3 AS SELECT (string_to_array(data, ','))[5] AS col5 FROM my_import_table;
 create table t_2 AS SELECT (string_to_array(data, ','))[3] AS col3, (string_to_array(data, ','))[4] AS col4 FROM my_import_table;
 create table t_1 AS SELECT (string_to_array(data, ','))[1] AS col1, (string_to_array(data, ','))[2] AS col2 FROM my_import_table;
(3 rows)

testdb=# DO $outer$
DECLARE
stmt text;
BEGIN
FOR stmt IN
with
settings as (select 2 as max_cols_per_table, 'my_import_table' as import_table, 'data' as column_name),
computed_settings1 as (select array_length(string_to_array(d, ','), 1) as num_cols from t limit 1),
computed_settings2 as (select (ceil((select num_cols::float from computed_settings1) / (select max_cols_per_table from settings)))::integer as num_tables),
columns_exprs as (select i, '(string_to_array('||(select column_name from settings)||$$, ','))[$$||i||'] AS col'||i as cexpr from generate_series(1, (select num_cols from computed_settings1)) as i),
column_exprs_by_table as (select t, cexpr from generate_series(1, (select num_tables from computed_settings2)) as t join columns_exprs ce
on i>((t-1)*(select max_cols_per_table from settings))
AND i<=(t*(select max_cols_per_table from settings))
),
create_table_stmts as (select 'create table t_'||t||' AS SELECT '||string_agg(cexpr, ', ')||' FROM '||(select import_table from settings)||';' from column_exprs_by_table group by t)
select * from create_table_stmts
LOOP
EXECUTE stmt;
END LOOP;
END;
$outer$;
DO
testdb=# select * from t_1;
 col1 | col2 
------+------
 c1   | c2
 r1c1 | r1c2
 r2c1 | r2c2
(3 rows)

testdb=# select * from t_2;
 col3 | col4 
------+------
 c3   | c4
 r1c3 | r1c4
 r2c3 | r2c4
(3 rows)

testdb=# select * from t_3;
 col5 
------
 c5
 r1c5
 r2c5
(3 rows)