我试图忽略csv文件,我上传通过命令行到PostgreSQL非法格式的日期:DATESTYLE忽略格式的PostgreSQL
Error: date/time field value out of range:"199999999"
的问题是,我不能在CSV更改数据文件,所以我必须找到导入这个错误日期的方法。
我试图忽略csv文件,我上传通过命令行到PostgreSQL非法格式的日期:DATESTYLE忽略格式的PostgreSQL
Error: date/time field value out of range:"199999999"
的问题是,我不能在CSV更改数据文件,所以我必须找到导入这个错误日期的方法。
使用中间表(loaded_data
)来存储您从CSV获得的数据。确保该表中的所有列都是text
类型,以便PostgreSQL几乎可以接受(除非您的行的列数不正确)。
一旦你在该表中的所有数据,消毒所有列,这样,当它们的值是不正确的,你要么将它们设置为NULL
,丢弃(DELETE
它们)或设置这些列的默认值。你实际做的将取决于你的特定应用。
最简单的(尽管可能不是最快的)方式来清理您的数据是使用函数CAST
您的文本到适当的类型,并处理异常如果输入格式不正确。对于date
类型的情况下,可以使用以下功能:
-- Create a function to get good dates... and return NULL if they're not
CREATE FUNCTION good_date(date_as_text text)
RETURNS DATE /* This is the type of the returned data */
IMMUTABLE STRICT /* If you pass a NULL, you'll get a NULL */
LANGUAGE PLPGSQL /* Language used to define the function */
AS
$$
BEGIN
RETURN CAST(date_as_text AS DATE) ;
EXCEPTION WHEN OTHERS THEN /* If something is wrong... */
RETURN NULL ;
END
$$ ;
注意,这个函数的行为将取决于你的设置datestyle
。但是,它始终与January 8, 1999
之类的文本一起工作,并且将返回NULL
以获得诸如2017-02-30
或February 30, 2017
之类的日期。
您将执行good_integer
函数的等效项。
让我们假设你有这样的输入数据:
CREATE TABLE loaded_data
(
some_id text,
some_date text
) ;
-- Let's assume this is the equivalent of loading the CSV...
INSERT INTO loaded_data
(some_id, some_date)
VALUES
(1, '20170101'),
(2, '19999999'),
(3, 'January 1, 1999'),
(4, 'February 29, 2001'),
(5, '20170230');
...这要存储下表中的信息:
CREATE TABLE destination_table
(
id integer PRIMARY KEY,
a_date date
) ;
...你” d使用:
INSERT INTO destination_table
(id, a_date)
SELECT
good_integer(some_id) AS id, good_date(some_date) AS a_date
FROM
loaded_data ;
而且你会得到:
SELECT * FROM destination_table;
id | a_date -: | :--------- 1 | 2017-01-01 2 | null 3 | 1999-01-01 4 | null 5 | null
检查所有的设置在dbfiddle here
替代方案:用一些ETL工具],可以执行类似的功能。我介绍的场景在某种程度上是一个非常简单的LTE(加载,转换,提取)等效。