use*_*745 9 r google-bigquery bigrquery tidyverse-api gargle
当使用从bigrqueryř中,tidyverse API请求进行认证,其中,一旦提供,允许从R会话访问大量查询。下载结果可能很耗时,如果 oauth 令牌在传输中到期,则下载失败:
错误:凭据无效 [authError]
# install.packages("tidyverse"); install.packages('bigrquery')
Sys.setenv(BIGQUERY_TEST_PROJECT="your-gcp-project-id")
library(tidyverse)
library(dbplyr)
library(bigrquery)
billing <- bq_test_project()
connection <- dbConnect(
bigrquery::bigquery(),
project = "your-gcp-project-id",
dataset = "dataset-name",
billing = billing
)
mytable <- tbl(connection, "mytable")
mytable %>%
-- some heavy dplyr wrangling --
%>% collect()
Run Code Online (Sandbox Code Playgroud)
哪个返回
Running job [/] 20s
Complete
Billed 400GB
Downloading 230,000,000 rows
Downloading data [=====--------] 28% ETA: 24h
Run Code Online (Sandbox Code Playgroud)
但过了一段时间
Error: Invalid Credentials [authError]
Run Code Online (Sandbox Code Playgroud)
如何增加 0Auth 令牌到期前的时间长度?
这不是一个完整的答案,而是迄今为止我研究的细节,以防止人们重蹈我的覆辙。
dbconnect
接受驱动程序和传递给驱动程序的参数(文档)dbConnect(drv, ...)
:。timeout
。本期有一个使用 Cassandra 的示例:con <- dbConnect(odbc::odbc(), "Cassandra (DSN)", timeout = 10)
。bigquery
。该文档列出了以下参数 ( project
、dataset
、billing
、page_size
、quiet
、use_legacy_sql
、bigint
) 并指出其他参数当前被忽略。因此,考虑到上述情况,超时似乎不太可能由 R 通过dbplyr
或DBI
连接来控制。
虽然不是 OP 的偏好(评论已经明确),但这仍然是一个潜在的解决方案。我使用基于唯一 ID 列的过滤方法,并使用包装函数来减少一些额外的混乱:
reconnect <- function(jj){
if(exists("connection"))
dbDisconnect(connection) # avoids multiple concurrent connections
print(paste0(as.character(Sys.time()),"-- modulo ",jj," begun")) # track progress
connection <- dbConnect(
bigrquery::bigquery(),
project = "your-gcp-project-id",
dataset = "dataset-name",
billing = billing
)
mytable <- tbl(connection, "mytable") %>%
filter(unique_id %% NUM_SUBSETS == jj) # filter to subset, requires unique_id
# assignment into the parent environment
assign("connection", connection, envir = parent.frame())
assign("mytable ", mytable , envir = parent.frame())
}
Run Code Online (Sandbox Code Playgroud)
然后我们迭代如下:
## parameters
DEVELOPMENT_MODE = FALSE
NUM_SUBSETS = 50
## subset
modulo = if(DEVELOPMENT_MODE){ modulo = 0 # only one if development mode
} else { modulo = 0:(NUM_SUBSETS-1) # otherwise all of them
}
results = data.frame()
for(jj in modulo){
reconnect(jj)
these_results = mytable %>%
-- some heavy dplyr wrangling --
%>% collect()
results = rbind(results, these_results)
}
Run Code Online (Sandbox Code Playgroud)
我DEVELOPER_MODE
在测试/开发时设置为 true,当我希望整个过程运行时设置为 false。
-- heavy dplyr wrangling here --
。因为 dbplyr 不能转换非常高效的 SQL 代码,所以在我在 SQL Server 上的工作中,保存中间表已经减少了我的运行时间。鉴于下载 10GB 的速度应该比几个小时快得多,瓶颈可能是 bigquery 即时执行所有争论(并且最初的 20 秒执行是惰性评估)。此链接表明单次执行的持续时间有六小时的限制。