使用 COPY 导入超过 1,000 个格式化数字时出现问题
Issue with importing formatted numbers over 1,000 with COPY
我有一个 Postgres 数据库,一直在尝试使用以下代码将 CSV 文件导入 table。我一直收到错误
ERROR: invalid input syntax for type numeric: " 1,183.26 "
我认为问题是值中有一个 ,
,但是当我进入 CSV 并尝试编辑该值时,,
似乎是由 [= 自动添加的25=].
COPY invtest5
FROM 'C:\Users\Hank\Downloads\SampleData\SampleDataCSV.csv'
DELIMITER ','
CSV HEADER;
table定义:
CREATE TABLE invtest5 (
OrderDate date,
Region varchar(255),
Rep varchar(255),
Item varchar(255),
Units int,
Unit_Cost numeric(15,3),
Total numeric(15,3)
);
我正在寻找一种方法来导入数据,无论该号码是否包含 ,
。
'1,183.26' 不是有效的 numeric literal. COPY
是快速和简单的,但不是 fault-tolerant。需要有效输入。
一些要修复的选项:
格式化 Excel 中的数字,不要使用“组分隔符”(这就是干扰 ,
的原因)。
编辑 CSV 以删除组分隔符。 (但不要删除其他逗号!)
如果您能够 ALTER
目标 table 中的列类型(即 没有 数据库上的并发负载,您拥有必要的权限,并且没有会阻塞的依赖对象),您可以:
ALTER TABLE invtest5
ALTER unit_cost TYPE text
, ALTER total TYPE text; -- both columns?
COPY ...
ALTER TABLE invtest5
ALTER unit_cost TYPE numeric(15,3) USING (replace(unit_cost, ',', '')::numeric)
, ALTER total TYPE numeric(15,3) USING (replace(total , ',', '')::numeric);
表达式 (replace(unit_cost, ',', '')::numeric)
在转换为 numeric
.
之前删除所有逗号
转换中的前导和尾随空格会自动修剪。
如果 table 中已经有一些行,现有值也会来回转换,这会触发整个 table 重写并使 table 膨胀。 大 tables 效率不高。
- 如果您无法轻松修复 CSV 并且无法对目标进行修补 table(或者只是不想让它膨胀),请使用 临时暂存 table 作为
COPY
目标,然后从那里 INSERT
:
CREATE TEMP tmp_invtest5 AS TABLE invtest5 LIMIT 0; -- copy basic structure
ALTER TABLE tmp_invtest5
ALTER unit_cost TYPE text
, ALTER total TYPE text; -- both columns?
COPY TO tmp_invtest5 ...
INSERT INTO invtest5
(orderdate, region, rep, item, units, unit_cost, total)
SELECT orderdate, region, rep, item, units, replace(unit_cost, ',', '')::numeric
, replace(total , ',', '')::numeric
FROM tmp_invtest5
-- ORDER BY ??? -- while being at it?
临时 table 在会话结束时自动删除。如果你需要它在那之前消失,DROP TABLE tmp_invtest5;
.
相关:
- How to update selected rows with values from a CSV file in Postgres?
我有一个 Postgres 数据库,一直在尝试使用以下代码将 CSV 文件导入 table。我一直收到错误
ERROR: invalid input syntax for type numeric: " 1,183.26 "
我认为问题是值中有一个 ,
,但是当我进入 CSV 并尝试编辑该值时,,
似乎是由 [= 自动添加的25=].
COPY invtest5
FROM 'C:\Users\Hank\Downloads\SampleData\SampleDataCSV.csv'
DELIMITER ','
CSV HEADER;
table定义:
CREATE TABLE invtest5 (
OrderDate date,
Region varchar(255),
Rep varchar(255),
Item varchar(255),
Units int,
Unit_Cost numeric(15,3),
Total numeric(15,3)
);
我正在寻找一种方法来导入数据,无论该号码是否包含 ,
。
'1,183.26' 不是有效的 numeric literal. COPY
是快速和简单的,但不是 fault-tolerant。需要有效输入。
一些要修复的选项:
格式化 Excel 中的数字,不要使用“组分隔符”(这就是干扰
,
的原因)。编辑 CSV 以删除组分隔符。 (但不要删除其他逗号!)
如果您能够
ALTER
目标 table 中的列类型(即 没有 数据库上的并发负载,您拥有必要的权限,并且没有会阻塞的依赖对象),您可以:
ALTER TABLE invtest5
ALTER unit_cost TYPE text
, ALTER total TYPE text; -- both columns?
COPY ...
ALTER TABLE invtest5
ALTER unit_cost TYPE numeric(15,3) USING (replace(unit_cost, ',', '')::numeric)
, ALTER total TYPE numeric(15,3) USING (replace(total , ',', '')::numeric);
表达式 (replace(unit_cost, ',', '')::numeric)
在转换为 numeric
.
转换中的前导和尾随空格会自动修剪。
如果 table 中已经有一些行,现有值也会来回转换,这会触发整个 table 重写并使 table 膨胀。 大 tables 效率不高。
- 如果您无法轻松修复 CSV 并且无法对目标进行修补 table(或者只是不想让它膨胀),请使用 临时暂存 table 作为
COPY
目标,然后从那里INSERT
:
CREATE TEMP tmp_invtest5 AS TABLE invtest5 LIMIT 0; -- copy basic structure
ALTER TABLE tmp_invtest5
ALTER unit_cost TYPE text
, ALTER total TYPE text; -- both columns?
COPY TO tmp_invtest5 ...
INSERT INTO invtest5
(orderdate, region, rep, item, units, unit_cost, total)
SELECT orderdate, region, rep, item, units, replace(unit_cost, ',', '')::numeric
, replace(total , ',', '')::numeric
FROM tmp_invtest5
-- ORDER BY ??? -- while being at it?
临时 table 在会话结束时自动删除。如果你需要它在那之前消失,DROP TABLE tmp_invtest5;
.
相关:
- How to update selected rows with values from a CSV file in Postgres?