7

我正在尝试从 PostgreSQL 数据库中提取数据,但时间戳字段的结果不一致。我不确定我是否正确处理了 POSIXct 结果。否则,我想我在 RPostgreSQL 包中发现了一个错误。这是复制问题的方法:

假设 postgres 数据库中有一个表,其中包含一个字段(在 PostgreSQL 中运行):

CREATE DATABASE mydb;
CREATE TABLE test_table
(   
  "DateTime" timestamp without time zone NOT NULL,
  CONSTRAINT "pk_test_table" PRIMARY KEY ("DateTime")
)
WITH (
  OIDS=FALSE
);
ALTER TABLE test_table
  OWNER TO postgres;

假设有几百条记录。我将在 R 中填充它们。这是代码:

library(RPostgreSQL)

# Let's feed the table with some sequence of date/time values
date_values <-  as.chron(seq(10000, 10500, 1/24))

format.chron <- function(z)  {
  sprintf("%04.0f-%02.0f-%02.0f %02.0f:%02.0f:00", 
            as.numeric(as.character(years(z))), 
            months(z), 
            as.numeric(as.character(days(z))), 
            as.numeric(as.character(hours(z))), 
            as.numeric(as.character(minutes(z))))
}

.generateInsertQuery <- function(date_values, field_name, table_name) {
  insert_val  <- paste(paste0("(", sQuote(format(date_values)), ")"), collapse=',')
  qry         <- paste("INSERT INTO", dQuote(table_name), paste0("(", dQuote(field_name), ")"), "VALUES", insert_val)
  qry
}

drv <- dbDriver('PostgreSQL')
con <- dbConnect(drv, user='postgres', dbname='mydb')
qry <- .generateInsertQuery(date_values, "DateTime", "test_table")
dbSendQuery(con, qry)

如果我尝试获取这些值,则时间分量会从结果数据中剔除

res <- dbGetQuery(con, "SELECT * FROM test_table")
res[1:20,1]

然而,结果的类别是 POSIXct

class(res[,1])

如果一次获取一条记录的结果,则 hour:min 等于 00:00 的值会丢失时间分量:

rs <- dbSendQuery(con, "SELECT \"DateTime\" FROM test_table")
res_list <- list()
for(i in 1:100) res_list[i]  <- fetch(rs,1)
res_list

作为一种解决方法,我一次获取结果 1 条记录,修复它们并将它们聚合到 data.frame 中。但这非常耗时,尤其是对于大型数据集。关于为什么会发生这种情况以及如何处理这个问题的任何想法?

提前致谢!

4

2 回答 2

5

dbWriteTable带有任何 posixct 字段的RPostgreSQL 将timestamp with timezone始终使用 tz创建类型的数据库字段,+00无论它将是什么 posixct 时区。我相信更精确的是创造timestamp without timezone

dbReadTable两者的最佳解决方案dbWriteTable是使用Sys.setenv(TZ = "UTC"). 在我看来,它的依赖性太深,因为 R 会话中的许多其他进程可能需要适当的时区设置。

更具体且不依赖于深度依赖的是定义自己的dbReadTable并且使用 posixct 类型的适当预处理/后处理dbWriteTable包装版本。DBI但是,如果您正在开发符合 DBI 的代码/包(不仅与 postgres 相关),它仍然不是一个选项。

将 RPostgreSQL 迁移到 github 以便于贡献会很棒。

于 2014-07-06T11:17:37.283 回答
3

首先,RPostgreSQL 项目有一个邮件列表;我建议你在那里发帖。

PostgreSQL 有两种日期时间类型:有和没有时区。我记得,R 只映射后者。我确实为此编写了一些早期的回归测试(请参阅包源),但最近没有参与该项目。但我确实记得 POSIXct 来回映射到 PostgreSQL 日期时间类型就好了。

于 2013-07-19T20:12:56.753 回答