PostgreSQL,R和没有时区的时间戳

时间:2014-02-21 10:58:04

标签: r postgresql timezone timestamp data.table

我正在阅读一个大的csv(对我来说大于1GB!)。它包含一个时间戳字段。 我从优秀的data.table包中读取了它(开始有100行)。

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

问题1(已解决):时间戳字段(称为&#34; ts&#34;和&#34;更新&#34;),例如&#34; 02/12/2014 04:40:00 AM&#34;转换为字符串。我使用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(未解决):由于原始数据帧时间戳字段具有时区,因此将创建一个表,其中包含字段&#34;时间戳和时区&#34;。最终,数据需要存储在一个表中,其中字段配置为&#34;时间戳没有时区&#34;。

但是在Postgres的表格中,数据存储为&#34; 2014-02-12 04:40:00.0&#34;,其中.0末尾是UTC偏移量。我想我需要&#34; 2014-02-12 04:40:00&#34;。

我试过

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

然后我复制了。当Postgres接受ALTER COLUMN命令时,当我尝试复制(使用INSERT INTO tbls SELECT ...)时,我收到错误:

   "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不受欢迎(但为什么Postgres会接受ALTER COLUMN?boh!)。

我尝试在CAST查询中使用INSERT INTO执行错误建议:

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

但我得到同样的错误(包括使用CAST aargh的建议!)

由PivotalR直接创建的表(基于数据框)具有以下CREATE脚本:

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

我插入的表格中有这个CREATE脚本:

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;

我为复杂的解释道歉,但可能会在链中的任何一步找到解决方案,所以我倾向于将所有步骤放在一个问题中。我相信必须有一个更简单的方法...

1 个答案:

答案 0 :(得分:2)

我认为你对在表之间复制数据感到困惑。

没有列列表的

INSERT INTO ... SELECT期望源和目标中的列相同。它没有按名称神奇地匹配列,它只是从左到右分配SELECTINSERT的列,直到它用完列,此时假定任何剩余的cols为空。所以你的查询:

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的类型在两个表之间是不同的。