我想创建一个从sql源读取的spark作业(使用' spark_read_jdbc')然后将结果写入一个镶木地板文件(' spark_write_parquet')。
对于sql语句中的小增量,需要多次执行此操作。我希望懒惰地创建这个工作,以便多个执行者可以接受这份工作。以下是一些示例玩具代码:
sql = "SELECT * FROM TBL_%s"
for(i in seq(1,10)){
sql_to_read = sprintf(sql, i)
optionSet$dbtable = paste0("(", sql_to_read ,") foo")
TEMP = spark_read_jdbc(sc, "TEMP", options = optionSet, memory = FALSE)
TEMP = TEMP %>% mutate(id := i)
TEMP %>% spark_write_parquet(., path = "/TEMP.parquet", mode = "append", partition_by = id)
}
问题是写操作不能延迟执行强制执行串行操作。有没有办法编写这个代码,以便简单地为完整的操作创建一个spark工作,然后当我踢一个' collect'语句多个执行程序将执行操作吗?
答案 0 :(得分:3)
您始终可以使用代码的结构来完全避免问题。因为所有写入都使用相同的输出表,所以您可以将输入定义为单个联合:
xs <- 1:10
query <- glue::glue("SELECT {xs} AS _id, * FROM TBL_{xs}") %>%
glue::collapse(" UNION ALL \n")
然后
optionSet$dbtable <- glue::glue("({query}) tmp")
spark_read_jdbc(sc, "TEMP", options = optionSet, memory = FALSE) %>%
spark_write_parquet(., path = "/TEMP.parquet", mode = "append", partition_by = id)
您还可以将id
用作partitionColumn
,并将min(xs)
/ max(xs)
用作lowerBound
/ upperBound
至parallelize reads。