带有 DBI/SQL 数据库的 R 目标

问题描述 投票:0回答:1

我有一个目标管道,应该填充并使用 DBI 数据库(在本例中为 duckdb。出于性能原因选择 SQL 和 duckdb)。

如何有效地将

{targets}
与 SQL 表结合使用。

一个可重现的最小示例看起来像这样,它读取两个数据集,组合它们,创建一个模型和一个图。

# in _targets.R
library(targets)

# preparation once:
# d <- ggplot2::mpg |> dplyr::mutate(id = 1:dplyr::n())
# write_csv(d |> dplyr::select(id, cty), "data1.csv")
# write_csv(d |> dplyr::select(id, displ, cyl), "data2.csv")

get_data <- function(file) {
  read_csv(file, col_types = cols()) %>%
    as_tibble()
}

combine_data <- function(d1, d2) {
  left_join(d1, d2, by = "id")
}

fit_model <- function(data) {
  lm(cty ~ displ + cyl, data) |> 
    coefficients()
}

plot_model <- function(model, data) {
  ggplot(data) +
    geom_point(aes(x = displ, y = cty, color = cyl)) +
    geom_abline(intercept = model[1], slope = model[2]) +
    theme_gray(24)
}

tar_option_set(packages = c("tibble", "readr", "dplyr", "ggplot2"))

list(
  tar_target(file1, "data1.csv", format = "file"),
  tar_target(file2, "data2.csv", format = "file"),
  tar_target(data1, get_data(file1)),
  tar_target(data2, get_data(file2)),
  tar_target(data, combine_data(data1, data2)),
  tar_target(model, fit_model(data)),
  tar_target(plot, plot_model(model, data))
)

# run: tar_make() -> runs all targets
# change a value in data2.csv -> tar_make() -> rebuilds only dependencies

这应该与数据库连接一起使用

# write to Database
con <- DBI::dbConnect(duckdb::duckdb(), "data.db")
on.exit(DBI::dbDisconnect(con, shutdown = TRUE), add = TRUE)
DBI::dbWriteTable(con, "data1", d |> dplyr::select(id, cty))
DBI::dbWriteTable(con, "data2", d |> dplyr::select(id, displ, cyl))

# in _targets.R... unclear at best...
list(
  tar_target(data1, ???), # if I use DBI::dbReadTable(con, "data1") it duplicates the data and returns it to R
)

问题是,如果我将表的值返回给 R,这可能会花费太长时间。是否有针对目标的数据库感知适配器,这对于目标是否可能/有意?

r dbi targets-r-package
1个回答
0
投票

我也经历过同样的尴尬,并因此创建了sqltargets。我现在使用的模式是:

load_tables_to_db <- function(...) {
  tables <- lst(...)
  path_to_db <- fs::path(Sys.getenv("S_DR_DP"), glue::glue("Databases/WFC_DB.duckdb"))

  con <- DBI::dbConnect(
    duckdb::duckdb(),
    dbdir = path_to_db,
    read_only = FALSE
  )
  on.exit(DBI::dbDisconnect(con, shutdown = TRUE))
  walk2(tables, names(tables), \(df, nm) DBI::dbWriteTable(conn = con, name = nm, value = df, overwrite = TRUE))
}

_targets.R

  tar_target(
    tables_loaded_to_db,
    load_tables_to_db(
      table1,
      table2,
      ...

    )
  ),
  tar_sql(report1, "query1.sql"),
  tar_sql(report2, "query2.sql")

tar_sql
将创建文件的上游目标(例如“report1_query_file”),而“report1”包含查询结果。 SQL 文件的标头中必须包含连接字符串。可以在注释中指定依赖关系(例如“--tar_load(table1)”)

该软件包是全新的,仍然是 WIP,但可能有助于简化您的工作流程。

© www.soinside.com 2019 - 2024. All rights reserved.