7

PostgreSQL データベースからデータを取得しようとしていますが、タイムスタンプ フィールドの結果に一貫性がありません。POSIXct の結果を適切に処理しているかどうかはわかりません。そうでなければ、RPostgreSQL パッケージにバグを見つけたと思います。問題を再現する方法は次のとおりです。

postgres データベースに 1 つのフィールドを持つテーブルがあるとします (これを 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])

結果が一度に 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

posixctフィールドを持つ RPostgreSQL は、posixct タイムゾーンに関係なく、常に tzdbWriteTable型のデータベース フィールドを作成します。代わりに作成する方が正確だと思います。timestamp with timezone+00timestamp without timezone

dbReadTableと の両方に最適なソリューションdbWriteTableは、 を使用することSys.setenv(TZ = "UTC")です。私の意見では、R セッションの他の多くのプロセスで適切なタイムゾーン設定が必要になる可能性があるため、依存関係が深すぎます。

より具体的で、深く依存しないのは、posixct 型の適切な前処理/後処理でバージョンをラップする独自dbReadTableのものを定義することです。しかし、DBI 準拠のコード/パッケージ (postgres 関連だけでなく) を開発している場合は、まだオプションではありません。dbWriteTableDBI

より簡単に貢献できるように、RPostgreSQL を github に移行することは素晴らしいことです。

于 2014-07-06T11:17:37.283 に答える
3

まず、RPostgreSQL プロジェクトにはメーリング リストがあります。そこに投稿することをお勧めします。

PostgreSQL には、タイムゾーンありとタイムゾーンなしの 2 つの日時型があります。私が思い出したように、R は後者のみをマッピングします。このための初期のリグレッション テストをいくつか書きましたが (パッケージ ソースを参照)、最近のプロジェクトにはあまり関与していません。しかし、私は POSIXct が PostgreSQL の日時型にうまく対応していることを思い出しました。

于 2013-07-19T20:12:56.753 に答える