在使用RPostgreSQL提取数据时,是否有一种特定的方法来处理R中的时间戳列?
我试图从PostgreSQL数据库中提取数据,但时间戳字段的结果不一致。我不确定是否正确处理POSIXct结果。否则,我想我在RPostgreSQL包中发现了一个bug。以下是复制问题的方法: 假设postgres数据库中有一个表,其中有一个字段(在PostgreSQL中运行此字段): 假设有几百条记录。我将在R中填充它们。以下是代码:在使用RPostgreSQL提取数据时,是否有一种特定的方法来处理R中的时间戳列?,r,posixct,rpostgresql,R,Posixct,Rpostgresql,我试图从PostgreSQL数据库中提取数据,但时间戳字段的结果不一致。我不确定是否正确处理POSIXct结果。否则,我想我在RPostgreSQL包中发现了一个bug。以下是复制问题的方法: 假设postgres数据库中有一个表,其中有一个字段(在PostgreSQL中运行此字段): 假设有几百条记录。我将在R中填充它们。以下是代码: library(RPostgreSQL) # Let's feed the table with some sequence of date/time val
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)
如果一次获取一条记录的结果,则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
rs首先,RPostgreSQL项目有一个邮件列表;我建议你发到那里
PostgreSQL有两种日期时间类型:带时区和不带时区。我记得,R只映射后者。我确实为此编写了一些早期回归测试(参见包源代码),但最近没有参与过该项目。但我确实记得POSIXct来回映射到postgresqldatetime类型很好 RPostgreSQL的dbWriteTable
和任何posixct字段将创建带有时区的时间戳类型的数据库字段
始终带有tz+00
,无论它是什么posixct时区。我相信更精确的方法是创建没有时区的时间戳
dbReadTable
和dbWriteTable
的最佳解决方案是使用Sys.setenv(TZ=“UTC”)
。
在我看来,这是太深的依赖性,因为R会话中的许多其他进程可能需要适当的时区设置
更具体且不依赖于深度的是定义自己的dbReadTable
和dbWriteTable
,它使用posixct类型的适当预处理/后处理来包装DBI
版本。但是,如果您正在开发符合DBI的代码/包(不仅仅是与postgres相关的),那么它仍然不是一个选项
将RPostgreSQL迁移到github以便于贡献,这将是一件好事。感谢@Dirk的建议。在我的例子中,我使用的是没有时区的时间戳,我仍然发现上面描述的问题。我会试试邮件列表。试试带时区的时间戳,看看是否有效。您可以始终使用UTC作为时区。再次感谢@Dirk提供的提示。从2000年到2010年,我能够毫无问题地推拉POSIXlt值的长向量。因此,似乎没有时区的时间戳是不受支持的类型。这甚至更好,因为我以前的方法在时区方面模棱两可,这可能会在数据用户之间造成混淆。这正是为什么我在所有这一切开始时选择带时区的时间戳。;-)如上所述,在CREATE TABLE
语句中使用带时区的timestamp
为我实现了这个技巧。虽然这不是问题的一部分,但根据我的经验,我发现在指定要写入的SQL表名时,dbWriteTable
不喜欢任何大写字母。
res <- dbGetQuery(con, "SELECT * FROM test_table")
res[1:20,1]
class(res[,1])
rs <- dbSendQuery(con, "SELECT \"DateTime\" FROM test_table")
res_list <- list()
for(i in 1:100) res_list[i] <- fetch(rs,1)
res_list