sql - 在dplyr中用转换后的数据替换SQL数据库表

标签 sql r sqlite dplyr

我在dplyr中转换数据时经常替换数据,尤其是在处理大型数据集时。当我使用SQL支持的数据集时,至少在使用SQLite时,我不确定如何优雅地做到这一点。

我在dplyr DB小插曲中或SO上都找不到关于此目标的任何讨论,这也使我想知道我最初所做的事情是否有问题。但是,这似乎是处理大型数据集的自然方法。

无论如何,最直观的方法不起作用:

library(dplyr)
library(RSQLite)

db2 <- src_sqlite("trouble.sqlite", create = TRUE)
trouble <- data.frame(values = c(5, 1, 3))
trouble.db <- copy_to(db2, trouble, temporary = FALSE)

collect(trouble.db) # 5, 3, 1

trouble.db <- trouble.db %>% arrange(values)
collect(trouble.db) # 1, 3, 5

trouble.in <- tbl(db2, sql("SELECT * from trouble"))
collect(trouble.in) # 5, 3, 1

就地复制的另一种直观语法给出“表已存在”错误:
trouble.db <- copy_to(db2, as.data.frame(trouble.db), name="trouble", temporary = FALSE)

一种解决方案是手动删除表并重建它,这就是我一直在做的:
db2$con %>% db_drop_table(table = "trouble")
trouble <- collect(trouble.db)
trouble.db <- copy_to(db2, trouble, temporary = FALSE)

另一个是放弃替换并创建一系列临时表,我觉得这些表没有美感,但我认为这可能是推荐的范例:
trouble_temp <- data.frame(values = c(5, 1, 3))
trouble_temp.db <- copy_to(db2, trouble_temp, temporary = TRUE)
trouble <- trouble.db %>% arrange(values)
trouble.db <- copy_to(db2, trouble, temporary = FALSE)

我怀疑“删除并重新复制”将成为答案,但是出于对精美解决方案的热爱,我想我会问是否有更好的方法。

最佳答案

对于以后发现的任何人。
该声明

trouble.db %>% arrange(values)
创建一个发送到数据库并在对结果进行collect编码后执行的SQL查询。
我们可以看到这样的SQL
trouble.db %>% arrange(values) %>% show_query()
SELECT *
FROM `trouble`
ORDER BY `values`
显然,像这样的查询无法修改其查询的实际数据。
要修改数据,我们可以使用dbWriteTable包中的DBI函数
library(dplyr)
library(RSQLite)

# Will use this connection object for all our DB interactions
con <- DBI::dbConnect(RSQLite::SQLite(), dbname = ":memory:")

trouble <- data.frame(values = c(5, 1, 3))
trouble.db <- copy_to(con, trouble, temporary = FALSE)

collect(trouble.db) # 5, 3, 1

# This is just a query
trouble.db <- trouble.db %>% arrange(values)
collect(trouble.db) # 1, 3, 5

# The data shouldn't be modified yet
trouble.in <- tbl(con, sql("SELECT * from trouble"))
collect(trouble.in) # 5, 3, 1

# Now we are modifying the data
DBI::dbWriteTable(
  con, "trouble", collect(trouble.db),
  overwrite = TRUE
)

tbl(con, sql("SELECT * from trouble")) %>% collect() # 1, 3, 5

关于sql - 在dplyr中用转换后的数据替换SQL数据库表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35343490/

相关文章:

mysql - sql中的简单查询条件

从 UTF-8 字符串中删除不可见字符

java - Android SQLite 使用数组更新列

android - 帮助 SQLite 查询

python - 选择查询非常慢,我怎样才能加快速度?

mysql - 使用 MySQL 进行条件计数

mysql - 使用字符串匹配对查询结果进行重复数据删除

android - 日志 : column _id does not exist (SQL related)

r - 将数据框中的一些观察结果按一列排列,将其他观察结果按另一列排列

r - 如何调整树状图(R)中x轴的大小?