2013-07-19 6 views
6

Я пытаюсь вытащить данные из базы данных PostgreSQL, а результаты для поля временной метки являются непоследовательными. Я не уверен, правильно ли я обрабатываю результаты POSIXct. В противном случае, я думаю, я нашел ошибку в пакете RPostgreSQL. Вот способ тиражирования вопрос:Существует ли конкретный способ обработки столбцов временной метки в R при извлечении данных с помощью 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]) 

Если результат выбирается одна записи в то время, значение с часами: мин равным 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. Но это очень трудоемко, особенно для больших наборов данных. Любые идеи о том, почему это происходит и как бороться с этой проблемой?

Заранее благодарен!

+0

Как упоминалось выше, использование 'timestamp with timezone' в заявлении' CREATE TABLE' сделало трюк для меня.Хотя это не является частью вопроса, по моему опыту я обнаружил, что 'dbWriteTable' не любит ** никаких заглавных букв при указании имен таблиц SQL для записи. – bibzzzz

ответ

3

Во-первых, проект RPostgreSQL имеет список рассылки; Я предлагаю вам разместить там.

PostgreSQL имеет два типа даты и времени: с часовым поясом и без него. Насколько я помню, R только отображает последнее. Я написал некоторые ранние регрессионные тесты для этого (см. Источник пакета), но не был связан с проектом в последнее время. Но я помню, что POSIXct отображает назад и вперед в тип даты и времени PostgreSQL.

+0

Спасибо @Dirk за предложение. В моем случае, я использую timestamp без часовой пояс, и я все еще нахожу проблему, описанную выше. Я попробую список рассылки. – JAponte

+1

Попробуйте «timestamp with timezone» и посмотрите, работает ли он. Вы всегда можете использовать UTC как часовой пояс. –

+0

Еще раз спасибо за подсказку @Dirk. Я был в состоянии вытащить длинный вектор значений POSIXlt с 2000 по 2010 год без проблем. Таким образом, кажется, что временная метка без часового пояса - неподдерживаемый тип. Это еще лучше, поскольку мой предыдущий подход был неоднозначным с точки зрения часового пояса, что может создать путаницу среди пользователей данных. – JAponte

4

RPostgreSQL-х dbWriteTable с любым полем posixct будет создавать базы данных поле типа timestamp with timezone всегда с TZ +00 независимо от того, что posixct часовой пояс будет. Я считаю, что более точным было бы создать вместо этого timestamp without timezone.

Лучшее решение для dbReadTable и dbWriteTable предназначено для использования Sys.setenv(TZ = "UTC"). По-моему, это слишком глубокая зависимость, потому что многие другие процессы в сеансе R могут требовать правильной настройки часового пояса.

Гораздо более специфичны и не глубоко зависит, чтобы определить собственный dbReadTable и dbWriteTable, который оборачивает версию DBI с соответствующим Preprocess/постобработки типов posixct. Но все же это не вариант, если вы разрабатываете DBI-совместимый код/​​пакет (не только связанные с postgres).

Было бы здорово, если бы RPostgreSQL перенесен на github для более легкого вклада.

+2

Смотрите новый проект RPostgres, который живет на GitHub ... – hadley

 Смежные вопросы

  • Нет связанных вопросов^_^