PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie bekomme ich mit dplyr lokale Daten in eine schreibgeschützte Datenbank?

Eine Möglichkeit besteht darin, etwas wie die folgende Funktion zu verwenden, die einen lokalen Datenrahmen mithilfe von SQL in einen entfernten Datenrahmen umwandelt, selbst wenn eine Nur-Lese-Verbindung verwendet wird .

df_to_pg <- function(df, conn) {

    collapse <- function(x) paste0("(", paste(x, collapse = ", "), ")")

    names <- paste(DBI::dbQuoteIdentifier(conn, names(df)), collapse = ", ")

    values <-
        df %>%
        lapply(DBI::dbQuoteLiteral, conn = conn) %>%
        purrr::transpose() %>%
        lapply(collapse) %>%
        paste(collapse = ",\n")

    the_sql <- paste("SELECT * FROM (VALUES", values, ") AS t (", names, ")")

    temp_df_sql <- dplyr::tbl(conn, dplyr::sql(the_sql))
    
    return(temp_df_sql)
}

Hier ist eine Illustration der verwendeten Funktion. Die Funktion wurde auf PostgreSQL und SQL Server getestet, funktioniert aber nicht auf SQLite (aufgrund fehlender VALUES Schlüsselwort, das auf diese Weise funktioniert). Ich glaube, es sollte auf MySQL oder Oracle funktionieren, da diese die VALUES haben Schlüsselwort.

library(dplyr, warn.conflicts = FALSE)
library(DBI)
   
pg <- dbConnect(RPostgres::Postgres())     

events <- tibble(firm_ids = 10000:10024L,
                 date = seq(from = as.Date("2020-03-14"), 
                            length = length(firm_ids), 
                            by = 1))
events
#> # A tibble: 25 x 2
#>    firm_ids date      
#>       <int> <date>    
#>  1    10000 2020-03-14
#>  2    10001 2020-03-15
#>  3    10002 2020-03-16
#>  4    10003 2020-03-17
#>  5    10004 2020-03-18
#>  6    10005 2020-03-19
#>  7    10006 2020-03-20
#>  8    10007 2020-03-21
#>  9    10008 2020-03-22
#> 10    10009 2020-03-23
#> # … with 15 more rows

events_pg <- df_to_pg(events, pg)
events_pg
#> # Source:   SQL [?? x 2]
#> # Database: postgres [[email protected]/tmp:5432/crsp]
#>    firm_ids date      
#>       <int> <date>    
#>  1    10000 2020-03-14
#>  2    10001 2020-03-15
#>  3    10002 2020-03-16
#>  4    10003 2020-03-17
#>  5    10004 2020-03-18
#>  6    10005 2020-03-19
#>  7    10006 2020-03-20
#>  8    10007 2020-03-21
#>  9    10008 2020-03-22
#> 10    10009 2020-03-23
#> # … with more rows