我之前写这个问题是为了了解 GitHub/hadley/dplyr。
http://stackoverflow.com/questions/21592266/i-cannot-connect-postgresql-schema-table-with-dplyr-package
感谢 dplyr、ggplots、reshape2 和 .....
@hadley想到你的答案我想写出完整的 SQL 语句
my_tbl = tbl(my_db, dplyr::sql('SELECT * FROM mortalidad.def0307'))
在那里我可以连接到架构和表。 非常感谢。 – 迭戈
在与 Greenplum 合作时,我只想发布同样的问题。 你的sql方法解决了我的问题。
我很高兴。 唯一让我担心的是,在sql语句中观察到以下内容
SELECT "var1", count(*) AS "n" FROM (SELECT * FROM mortalidad.mort12)
当任何分组完成时。 FROM后面有一个子查询,不知道这会不会对sql查询的效率有任何问题。 我是流行病学家,我不知道这一点。
你介意给我一个 SQL 命令序列,我可以在 postgresql 中运行这些命令来在该模式中创建一个模式和一个数据库吗?
抱歉在这里延迟我作为创建方案发送
创建表 schema_name.table_name
(
codigo 字符变化(3),
不同的字符(51),
大陆性格变化(7)
)
2014-03-19 18:56 GMT-03:00 Hadley Wickham通知@ github.com:
你介意给我一个我可以运行的 SQL 命令序列吗?
postgresql 在该模式中创建模式和数据库?直接回复本邮件或在Gi tHub上查看
.
迭戈·加西拉索
梅迪科
社会事务部
全国呼吸系统研究所
Av。 Blas Parera 8260 // 圣达菲 // 阿根廷 //0342 - 4896850
http://www.anlis.gov.ar/inst/iner/
我认为这里基本上有两种选择:
x.y
将转义为"x"."y"
。 这具有非常简洁的优点,它的缺点是从 R 转换为 SQL 的表不能在字段名称中使用.
(可能不是很常见)。ident()
以接受多个参数,例如ident("x", "y")
。 或者可以定义dot()
,它执行 NSE 以允许您编写dot(x, y)
。 这是更多的打字,但保证不会破坏任何现有的代码。这对于表名(例如schema.table
)和可能消除连接中的字段名称(例如table.field
)都很重要
我目前倾向于使用显式的dot()
函数,因为在全球范围内改变转义的工作方式似乎有风险。
嗯,对于这个用例,你可以这样做:
my_tbl <- tbl(my_db, sql('mortalidad.def0307'))
以及一些其他代码以供将来参考(未成功)
dot <- function(...) {
args <- dots(...)
is_name <- vapply(args, is.name, logical(1))
if (any(!is_name)) {
stop("All arguments to dot() must be names.")
}
dots <- vapply(args, as.character, character(1))
class(dots) <- c("ident_multi", "ident", "sql", "character")
dots
}
dot <- function(...) {
out <- paste(escape(c(...), parens = FALSE), collapse = ".")
class(out) <- c("ident", "sql", "character")
out
}
#' <strong i="6">@export</strong>
escape.ident_multi <- function(x, parens = FALSE, collapse = ", ", con = NULL) {
y <- vapply(x, escape_ident, FUN.VALUE = character(1), con = con)
paste(y, collapse = ".")
}
#' <strong i="7">@export</strong>
format.ident_multi <- function(x, ...) paste0("<SQL> ", paste(x, collapse = "."))
# lahman_sqlite() %>% tbl("Batting")
# lahman_sqlite() %>% tbl("main.Batting")
# lahman_sqlite() %>% tbl(sql("main.Batting"))
# lahman_sqlite() %>% tbl(dot("main", "Batting"))
嗨,哈德利,
我遇到了同样的问题,嵌套似乎是性能问题(在我的情况下,这是一个严重的问题,因为我正在处理具有 1 亿行的数据)。 你能详细说明你上次尝试失败的原因吗?
谢谢
FWIW,对于某些用例,一个有用的习语是:
dbSendQuery(con$con, build_sql("SET search_path TO ", schema_name))
然后使用该连接的后续查询在该模式内。
嗨哈兰,
谢谢 - 我已经在使用类似的东西(除了我通过架构扩展搜索路径。但到目前为止它只是有帮助。如果您在 2 个架构中有相同名称的表,它不会。
无论如何,我想知道为什么不在 base_scalar SQL 转换器中重载“$”符号。
从 r 的角度来看,这甚至是有意义的
a$b$c,会有一个环境(即模式)、ba 表和ca 列。 唯一需要修复的想法是 tbl_sql,如果 table_name 存在于数据库中,则不应以如此简单的方式进行检查。 相反,它可以检查“SELECT”语句是否是 SQL 查询的一部分,如果不是,则在前面添加一个 SELECT * 并以这种方式检查变量。
在这种情况下,甚至可以为 tbl 功能启用 NSE?
哦,是的,还有一条评论:
数据库发送查询
通常不适用于 RJDBC(至少对于 vertica)。 上面的查询,即 SET search_path TO ...
不返回结果。 dbSendQuery 确实需要一个。 对于 vertica,这不起作用,必须使用 dbSendUpdate。 MySQL 也是这种情况(或者至少 dbSendUpdate 不会对 MySQL 失败)?
我喜欢重载$
的想法。 当我下次在 dplyr 上工作时,我肯定会考虑它。
@hhoeflin您是否尝试过使用 RPostgreSQL 而不是 RJDBC 来与 vertica 交谈?
不 - 不知道 RPostgreSQL 是一个选项。 无论如何 - 现在已经为 RJDBC 实现了 vertica 后端。 虽然尝试过并遇到问题,因为它试图访问的 postgres 表找出数据库中存在的哪些表似乎不同。
这正在通过 DBI 慢慢解决: https :
最有用的评论
FWIW,对于某些用例,一个有用的习语是:
然后使用该连接的后续查询在该模式内。