我試圖忽略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(加載,轉換,提取)等效。