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
所以除非你需要修改数据库,否则我建议过滤而不是删除。
相当于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
所以除非你需要修改数据库,否则我建议过滤而不是删除。