2017-07-17 43 views
6

Potrzebuję zaktualizować warunkowe wartości kolumn w innych kolumnach w tabeli bazy danych PostgreSQL. Udało mi się to zrobić pisząc instrukcję SQL w R i wykonując ją z dbExecute z pakietu DBI.Czy mogę uruchomić instrukcję aktualizacji SQL przy użyciu tylko składni dplyr w R

library(dplyr) 
library(DBI) 

# Establish connection with database 
con <- dbConnect(RPostgreSQL::PostgreSQL(), dbname = "myDb", 
       host="localhost", port= 5432, user="me",password = myPwd) 

# Write SQL update statement 
request <- paste("UPDATE table_to_update", 
       "SET var_to_change = 'new value' ", 
       "WHERE filter_var = 'filter' ") 

# Back-end execution 
con %>% dbExecute(request) 

Czy można to zrobić, używając tylko składni dplyr? Próbowałem, z ciekawości,

con %>% tbl("table_to_update") %>% 
    mutate(var_to_change = if (filter_var == 'filter') 'new value' else var_to_change) 

który działa w R, ale oczywiście nic nie robi w dB, ponieważ wykorzystuje select oświadczenie. copy_to pozwala jedynie na append i overwite opcji, więc nie mogę zobaczyć, jak go używać, chyba że usuwając następnie dodanie przefiltrowane obserwacje ...

Odpowiedz

3

Aktualny dplyr 0.7.1 (z dbplyr 1.1.0) nie obsługuje tego , ponieważ zakłada, że ​​wszystkie źródła danych są niezmienne. Wydaje się, że najlepiej jest wydać UPDATE przez dbExecute().

Dla zastępując większy kawałek w tabeli, można również:

  1. Napisz ramkę danych do tabeli tymczasowej w bazie danych poprzez copy_to().
  2. Rozpocznij transakcję.
  3. Wydaj DELETE FROM ... WHERE id IN (SELECT id FROM <temporary table>)
  4. wydać INSERT INTO ... SELECT * FROM <temporary table>
  5. Commit transakcję

W zależności od schematu, może być w stanie zrobić jeden INSERT INTO ... ON CONFLICT DO UPDATE zamiast DELETE a następnie INSERT.