2014-02-21 103 views
0

我正在閱讀一個大的csv(對我來說大於1GB!)。它包含一個時間戳字段。 我從優秀的data.table包中讀取它(100行開始)與fread。PostgreSQL,R和沒有時區的時間戳

ddfr <- fread(input="~/file1.csv",nrows=100, header=T) 

問題1(解析):時間戳字段(稱爲 「TS」 和 「更新」),例如「02/12/2014 04:40:00 AM」被轉換爲字符串。我使用lubridate包mdh_hms將字段轉換回時間戳。燦爛。

ddfr$ts <- data.frame(mdy_hms(ddfr$ts)) 

問題2(沒有解決):將時間戳與時區爲每POSIXlt創建。

如何在R中創建沒有時區的時間戳?可能嗎??

現在我使用另一個(新的)很棒的軟件包PivotalR使用as.db.data.frame將數據框寫入PostGreSQL 9.3。它充當魅力。

x <- as.db.data.frame(ddfr, table.name= "tbl1", conn.id = 1) 

問題3(沒有解決):作爲原始數據幀時間戳字段有時間區,一個表與字段「時間戳與時區」創建。最終,數據需要存儲在一個表中,其中的字段被配置爲「沒有時區的時間戳」。

但在我的Postgres表中,數據存儲爲「2014-02-12 04:40:00」,最後的.0爲UTC偏移量。我想我需要有「2014-02-12 04:40:00」。

我試圖

ALTER TABLE tbl ALTER COLUMN ts type timestamp without time zone; 

然後我複製對面。而Postgres的接受ALTER COLUMN命令,當我嘗試(使用INSERT INTO tbls SELECT ...)來複制我得到一個錯誤:(?!但爲什麼那麼的Postgres接受ALTER COLUMN BOH)

"column "ts" is of type timestamp without time zone but expression is of type text 
    Hint: You will need to rewrite or cast the expression." 

顯然在最後.0不喜歡。

我試圖做的INSERT INTO查詢中使用CAST什麼建議的錯誤:

INSERT INTO tbl2 SELECT CAST(ts as timestamp without time zone) FROM tbl1 

,但我得到了同樣的錯誤

直接創建表(包括使用CAST AARGH的建議!)通過PivotalR(基於數據幀)有這個創建腳本:

CREATE TABLE tbl2 
(
    businessid integer, 
    caseno text, 
    ts timestamp with time zone 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE tbl1 
    OWNER TO mydb; 

我insertin表G成形有這個創建腳本:

CREATE TABLE tbl1 
(
    id integer NOT NULL DEFAULT nextval('bus_seq'::regclass), 
    businessid character varying, 
    caseno character varying, 
    ts timestamp without time zone, 
    updated timestamp without time zone, 
    CONSTRAINT busid_pkey PRIMARY KEY (id) 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE tbl1 
    OWNER TO postgres; 

我道歉了令人費解的解釋,但一個潛在的解決方案可以在鏈中的任何步驟中發現的,所以我更願意把一個問題我的所有步驟。我相信必須有一個更簡單的方法...

+0

請顯示您運行的所有SQL語句,包括它們的參數,而不僅僅是它們的塊。編輯問題在完成後添加信息和評論。 –

+0

完成!它絕對讀得更好。謝謝。 – Enzo

+0

您報告的錯誤與您顯示的SQL無關。當你使用CAST而不是另一個時,你確定它是*相同*錯誤嗎?如果是這樣,在'psql'中顯示你的表定義 - '\ dt tbl1'和'\ dt tbl2'。 –

回答

2

我認爲你對錶之間複製數據感到困惑。

INSERT INTO ... SELECT沒有列列表需要來自源和目標的列相同。它不會按名稱神奇地匹配列,它只會從SELECTINSERT從左到右分配列,直到列用完,此時任何剩餘的列都被假定爲空。所以,你的查詢:

INSERT INTO tbl2 SELECT ts FROM tbl1; 

不這樣做:

INSERT INTO tbl2(ts) SELECT ts FROM tbl1; 

它實際上採摘TBL2的第一列,這是businessid,所以實際上它試圖這樣做:

INSERT INTO tbl2(businessid) SELECT ts FROM tbl1; 

這顯然是無稽之談,而且沒有施法能夠解決這個問題。

(原始問題中的錯誤與您的表和查詢不匹配,因此詳細信息可能會有所不同,因爲您明顯在修改/混淆表格或發佈表格的新版本時出現錯誤錯誤原理仍然存在)

假設你的表定義不會改變,列順序也不會改變,這通常是一個非常糟糕的主意。所以一定要明確列的內容。在這種情況下,我認爲你的意圖可能實際上已經:

INSERT INTO tbl2(businessid, caseno, ts) 
SELECT CAST(businessid AS integer), caseno, ts 
FROM tbl1; 

注投,因爲businessid類型是兩個表之間的不同。

+0

你是對的!我的錯誤是忽略表格之間的對齊(相同的欄序列ID字段)。謝謝 – Enzo