你能说出 dbplyr 的模拟惰性表吗?

Can you name dbplyr's simulated lazy tables?

dbplyr 有一些看起来非常有用的模拟函数,所以你可以在没有连接到任何真实数据库的情况下编写查询,但我似乎无法将实际的 table 名称输入任何我这样写的查询。他们的名字都只是`df`,而且我之后似乎无法修改它们。事实上,我在查询对象或其属性的任何地方都看不到 `df`(它没有任何属性),所以现在我不知道 dbplyr 如何处理 table 名称全部.

MWE:

library(dbplyr)
library(dplyr, warn.conflicts = FALSE)
library(magrittr)
library(purrr, warn.conflicts = FALSE)

query <- tbl_lazy(df = mtcars)
query %$% names(ops)
#> [1] "x"    "vars"
show_query(query)
#> <SQL>
#> SELECT *
#> FROM `df`

# The actual data frame is stored in the object under the name `x`, but
# renaming it has no effect, unsurprisingly (since it wasn't named `df`
# anyway)
query %<>% modify_at("ops", set_names, "mtcars", "vars")
query %$% names(ops)
#> [1] "mtcars" "vars"
show_query(query)
#> <SQL>
#> SELECT *
#> FROM `df`

顺便说一句,我的用例是我需要 运行 SQL 在另一个具有实际服务器访问权限的系统中进行查询,所以我想要 R 脚本生成 SQL 语法已准备好在该系统中 运行,即使 R 无法连接到它。使用真实结构(table & 列名、列类型,但没有行)制作一个空的虚拟数据库是一种选择,但是,显然,只使用这些自由形式的模拟会更简单, 如果 SQL 可以生成准备剪切和粘贴。 (lazy_frame() 看起来更适合这种不存在的 table,但是,你猜怎么着,它实际上只是 tbl_lazy(tibble()) 的包装器,所以,同样的 `df` 名称问题。 )

reprex package (v0.3.0)

创建于 2019-12-12

我不知道有什么方法可以重命名模拟的 table。根据文档,simulate_* 函数的重点是在不实际连接到数据库的情况下测试数据库翻译。

当连接到远程 table 时,dbplyr 使用 tbl() 定义的数据库、架构和 table 名称。它还获取列名。因此,我建议在 R 可以连接到数据库的环境中进行开发。考虑以下因素:

# simulated
df_sim = tbl_lazy(mtcars, con = simulate_mssql())
df_sim %>% head(5) %>% show_query()

# output
<SQL>
SELECT TOP(5) *
FROM `df`

# actual
df = tbl('db_table_name', con = database_connection_object)
df %>% head(5) %>% show_query()

# output
<SQL>
SELECT TOP(5) col1, col2, col3
FROM "database"."db_table_name"

不仅 df 被 table 名称替换,模拟查询中的 * 也被第二个查询中的列名替换。

如果通过模拟生成 SQL 脚本很重要,您可能会考虑的一个选项是转换为文本、替换和转换回来。例如:

df_sim = tbl_lazy(mtcars, con = simulate_mssql())
query = df_sim %>% head(5) %>% as.character()
query = gsub("`df`", "[db].[schema].[table]", query)

# write query out to file
writeLines(query, "file.sql")
# OR create a remote connection
remote_table = tbl(db_connection, sql(query))

remote_table %>% show_query()
# output
<SQL>
SELECT TOP(5) *
FROM [db].[schema].[table]