dbplyr icon indicating copy to clipboard operation
dbplyr copied to clipboard

Add argument `check_unique` to `rows_update()`, `rows_patch()`, `rows_upsert()`

Open mgirlich opened this issue 2 years ago • 1 comments

Probably this is also needed in rows_insert()

mgirlich avatar Apr 25 '22 08:04 mgirlich

There is dm::check_key() that can help today:

library(dbplyr)

bad_update <- tibble::tibble(a = 1L, b = 3:4)

data <- memdb_frame(a = 1L, b = 2L)
print(dplyr::rows_update(data, bad_update, in_place = TRUE, copy = TRUE, unmatched = "ignore"))
#> Matching, by = "a"
#> # Source:   table<dbplyr_001> [1 x 2]
#> # Database: sqlite 3.38.2 [:memory:]
#>       a     b
#>   <int> <int>
#> 1     1     4

dplyr::rows_update(data, bad_update %>% dm::check_key(a), in_place = TRUE, copy = TRUE, unmatched = "ignore")
#> Error in `abort_not_unique_key()` at dm/R/key-helpers.R:52:4:
#> ! (`a`) not a unique key of `.`.
dplyr::rows_update(data, bad_update %>% dplyr::copy_to(remote_con(data), .) %>% dm::check_key(a), in_place = TRUE, unmatched = "ignore")
#> Error in `abort_not_unique_key()` at dm/R/key-helpers.R:52:4:
#> ! (`a`) not a unique key of `.`.
dplyr::rows_update(data, bad_update %>% head(1) %>% dplyr::copy_to(remote_con(data), ., overwrite = TRUE) %>% dm::check_key(a), in_place = TRUE, unmatched = "ignore")
#> Matching, by = "a"
data
#> # Source:   table<dbplyr_001> [1 x 2]
#> # Database: sqlite 3.38.2 [:memory:]
#>       a     b
#>   <int> <int>
#> 1     1     3

Created on 2022-04-29 by the reprex package (v2.0.1)

This leads to the greater question if a table's primary key should be a property of the table. I think it should. Foreign keys too, by the way -- this is trickier, but I have an idea. We can incubate in dm and discuss.

krlmlr avatar Apr 29 '22 21:04 krlmlr