有时,当通过 ROracle
和 dbplyr
连接到我的 Oracle
数据库时,我会运行 dplyr::collect
获取的数据超出预期且超出 R 处理能力的操作。
这可能会使 R 崩溃,并且通常表明我应该在获取之前进一步过滤或聚合数据。
如果能够在选择是否获取结果之前检查结果的大小(无需运行两次查询),那就太好了。
让我们将 collect2
命名为 collect
的变体,以实现此目的:
预期行为:
small_t <- con %>% tbl("small_table") %>%
filter_group_etc %>%
collect2(n_max = 5e6) # works fine
big_t <- con %>% tbl("big_table") %>%
filter_group_etc %>%
collect2(n_max = 5e6) # Error: query returned 15.486.245 rows, n_max set to 5.000.000
这可能吗?
我也愿意使用 ROracle
/DBI
而不使用 dplyr
的解决方案,例如:
dbGetQuery2(con, my_big_sql_query,n_max = 5e6) # Error: query returned 15.486.245 rows, n_max set to 5.000.000
编辑:
请参阅下面作为答案发布的部分解决方案,这不是最佳选择,因为浪费了一些时间来获取我没有用的数据。
最佳答案
这并不能解决您在评论中提到的关于花费资源来获取查询两次的问题,但它似乎确实有效(至少针对我的 MySQL 数据库——我没有 Oracle 数据库来实现)对其进行测试):
collect2 <- function(query, limit = 20000) {
query_nrows <- query %>%
ungroup() %>%
summarize(n = n()) %>%
collect() %>%
pull('n')
if(query_nrows <= limit) {
collect(query)
} else {
warning("Query has ", query_nrows,"; limit is ", limit,". Data will not be collected.")
}
}
我没有看到任何方法可以在不实际运行查询的情况下测试查询结果中的行数。不过,使用此方法时,您始终会强制首先在数据库中计算行数,如果行数超过 20,000(或无论行数限制是多少),则拒绝收集。
关于r - 仅当查询返回少于 n_max 行时收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47097641/