Как записать метки времени POSIXct / POSIXt с миллисекундами в таблицу Postgres из R - PullRequest
0 голосов
/ 11 октября 2019

У меня есть PostgreSQL 11 DB, которая содержит метки времени с миллисекундами (тип timestamp). Получение данных работает нормально - время составляет миллисекунды. Запись в базу данных приводит к обрезке миллисекунд до десятых секунд.

Как сэкономить миллисекунды при записи в Postgresql?

Это DBI? Я не связан с DBI. Было бы хорошо, хотя, так как я обычно использую бассейн. Любой интерфейс R-Postgres приветствуется.

Пример данных

    data <- structure(list(event_time = structure(c(1562053856.679, 1561977632.48, 
1561129860.825), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
name = c("E9980.RT_POS", "E9984.FT_POS", "E9984.RT_POS"), 
float_val = c(78.7, 90.54, 78.82)), class = c("tbl_df", "tbl","data.frame"), row.names = c(NA, -3L))



# Look like this
# A tibble: 3 x 3
event_time               name         float_val
<dttm>                   <chr>            <dbl>
1 2019-07-02 07:50:56.6789 E9980.RT_POS      78.7
2 2019-07-01 10:40:32.4800 E9984.FT_POS      90.5
3 2019-06-21 15:11:00.8250 E9984.RT_POS      78.8

Подключение к БД

library(odbc)
library(DBI)
library(dplyr)
library(dbplyr)
op <- options(digits.secs=4) # let me see milliseconds
con <- DBI::dbConnect(odbc::odbc(),
                  Driver = "PostgreSQL Driver", 
                  Server = "localhost", 
                  Database  = "postgres",
                  UID = "postgres",
                  PWD = rstudioapi::askForPassword("Database password"),
                  Port = 5432)

Запись в БД

dbWriteTable(con, "test", data)

Чтениеиз БД

con %>% tbl(in_schema("public","test")) %>% collect()

# A tibble: 3 x 3
event_time               name         float_val
<dttm>                   <chr>            <dbl>
1 2019-07-02 07:50:56.0000 E9980.RT_POS      78.7
2 2019-07-01 10:40:32.0000 E9984.FT_POS      90.5
3 2019-06-21 15:11:00.0000 E9984.RT_POS      78.8

или

dbReadTable(con,"test")
event_time         name float_val
1 2019-07-02 07:50:56 E9980.RT_POS     78.70
2 2019-07-01 10:40:32 E9984.FT_POS     90.54
3 2019-06-21 15:11:00 E9984.RT_POS     78.82

Запрос pgadmin также подтверждает, что миллисекунды записаны неправильно.

Сеанс и дополнительная информация

sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

locale:
[1] de_DE.UTF-8/de_DE.UTF-8/de_DE.UTF-8/C/de_DE.UTF-8/de_DE.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dbplyr_1.4.2 dplyr_0.8.3  DBI_1.0.0    odbc_1.1.6  

loaded via a namespace (and not attached):
[1] Rcpp_1.0.1       rstudioapi_0.10  knitr_1.23       magrittr_1.5     hms_0.5.0        tidyselect_0.2.5
[7] bit_1.1-14       R6_2.4.0         rlang_0.4.0      fansi_0.4.0      blob_1.2.0       tools_3.6.0     
[13] xfun_0.8         utf8_1.1.4       cli_1.1.0        bit64_0.9-7      assertthat_0.2.1 tibble_2.1.3    
[19] crayon_1.3.4     purrr_0.3.2      vctrs_0.2.0      zeallot_0.1.0    glue_1.3.1       compiler_3.6.0  
[25] pillar_1.4.2     backports_1.1.4  pkgconfig_2.0.2 





 rstudioapi::versionInfo()$version
 [1] ‘1.2.1335’

1 Ответ

1 голос
/ 11 октября 2019

Временные метки с разрешением менее секунды, как и ожидалось, вставляются с использованием драйвера postgres из RPostgres вместо odbc.

library(DBI)
library(RPostgres) #for Postgres driver
library(dplyr)
library(dbplyr)

#set output/print resolution
options(digits.secs=4) 

con <- DBI::dbConnect(RPostgres::Postgres(),
            dbname  = "postgres",
            user = "postgres",
            password = rstudioapi::askForPassword("Database password"),
            host = "localhost",
            port = 5432)


dbWriteTable(con, "test", data)

Sys.setenv(TZ = "UTC") #so next line prints in UTC

con %>% tbl(in_schema("public","test")) %>% collect()


# A tibble: 3 x 3
#  event_time               name         float_val
#  <dttm>                   <chr>            <dbl>
#1 2019-07-02 07:50:56.6779 E9980.RT_POS      78.7
#2 2019-07-01 10:40:32.4800 E9984.FT_POS      90.5
#3 2019-06-21 15:11:00.8250 E9984.RT_POS      78.8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...