2017-07-17 3 views
6

J'ai besoin de mettre à jour les valeurs de colonnes conditionnellement sur d'autres colonnes dans certaines tables de base de données PostgreSQL. J'ai réussi à le faire en écrivant une instruction SQL dans R et en l'exécutant avec dbExecute du paquet DBI.Puis-je exécuter une instruction de mise à jour SQL en utilisant uniquement la syntaxe dplyr dans 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) 

Est-il possible de le faire en utilisant seulement la syntaxe dplyr? J'ai essayé, par curiosité,

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

qui travaille en R, mais ne évidemment rien dans db car il utilise une instruction select. copy_to permet seulement pour append et overwite options, donc je ne vois pas comment l'utiliser à moins que la suppression puis les observations filtrées annexant ...

Répondre

3

dplyr actuelle 0.7.1 (avec dbplyr 1.1.0) ne supporte pas , car il suppose que toutes les sources de données sont immuables. L'émission d'un UPDATE via dbExecute() semble être le meilleur pari.

Pour remplacer un morceau plus grande dans une table, vous pouvez aussi:

  1. Ecrivez la trame de données à une table temporaire dans la base de données via copy_to().
  2. Démarrer une transaction.
  3. Émettre une DELETE FROM ... WHERE id IN (SELECT id FROM <temporary table>)
  4. Adresser une INSERT INTO ... SELECT * FROM <temporary table>
  5. valider la transaction

En fonction de votre schéma, vous pourriez être en mesure de faire un seul INSERT INTO ... ON CONFLICT DO UPDATE au lieu de DELETE puis INSERT.