dbplyr:从数据库中的 table 中删除行

dbplyr: delete row from a table in database

相当于DBI::dbSendQuery(con, "DELETE FROM <table> WHERE <condition>")dbplyr动词组合是什么。

我想要的不是从数据库中查询数据,而是从数据库中删除数据并更新table。

我想以 dplyr 的方式进行,但我不确定是否可行。我在包参考中找不到任何类似的东西。

dbplyr 将 dplyr 命令转换为查询数据库 tables。我不知道使用纯 dbplyr 修改现有数据库 tables 的任何内置方法。

这可能是一种设计选择。

  • 在 R 中,我们不需要区分从 table 获取数据(查询)和修改 table。这可能是因为在 R 中,如果 error/mistake 发生,我们可以将原始数据重新加载到内存中。
  • 但是在数据库中查询和修改 table 是故意不同的事情。修改数据库时,您正在修改源,因此需要使用额外的控件(因为恢复已删除的数据要困难得多)。

DBI 包可能是您修改数据库的最佳选择

这是我在所有 dbplyr 工作中使用的方法。通常是一个自定义函数,它接受由 dbplyr 翻译生成的查询并将其插入到 DBI 调用中(您可以在我的 dbplyr helpers GitHub 存储库中看到这方面的示例)。

为此考虑两种方法:(1) 反连接(在所有列上),然后编写新的 table,(2) DELETE FROM 语法。

反加入方法的模型

records_to_remove = remote_table %>%
  filter(conditions)

desired_final_table = remote_table %>%
  anti_join(records_to_remove, by = colnames(remote_table))

query = paste0("SELECT * INTO output_table FROM (",
               sql_render(desired_final_table),
               ") AS subquery")

DBI::dbExecute(db_con, as.character(query))

DELETE FROM 语法模型

records_to_remove = remote_table %>%
  filter(conditions)

query = sql_render(records_to_remove) %>%
  as.character() %>%
  gsub(search_term = "SELECT *", replacement_term = "DELETE")

DBI::dbExecute(db_con, query)

如果您计划多次 运行 这些查询,则建议将它们包装在一个函数中,并检查有效性。

对于某些用例,不需要删除行。

您可以将 R 中的 filter 命令视为 从 table 中删除 行。例如在 R 中我们可能 运行:

prepared_table = input_table %>%
  filter(colX == 1) %>%
  select(colA, colB, colZ)

并将此视为在生成输出之前删除 colX == 1 处的行:

output = prepared_table %>%
  group_by(colA) %>%
  summarise(sumZ = sum(colZ))

(或者你可以使用上面的反连接而不是过滤器。)

但对于这种类型的删除,您不需要编辑源数据,因为您可以在每次 运行 时过滤掉不需要的行。是的,它会使您的数据库查询更大,但这对于使用数据库来说是正常的。

所以结合SQL中的准备和输出是正常的(像这样):

SELECT colA, SUM(colZ) AS sumZ
FROM (

  SELECT colA, colB, colZ
  FROM input_table
  WHERE colX = 1

) AS prepared_table
GROUP BY colA

所以除非你需要修改数据库,否则我建议过滤而不是删除。