是否可以运行 SQL直接在classtbl_sql(或tbl_dbi)上查询?
Is it possible to run SQL query directly on class tbl_sql (or tbl_dbi)?
示例代码:
library(DBI)
library(RSQLite)
# will require more details (like user, password, host, port, etc.)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
data(USArrests)
dbWriteTable(con, "USArrests", USArrests)
dbListTables(con)
d0 <- tbl(con, "USArrests")
dbGetQuery(d0, "select * from USArrests")
dbGetQuery(d0, "select * from d0")
哪个returns:
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘dbGetQuery’ for signature ‘"tbl_dbi", "character"’
显然我可以在 con 上使用 dbGetQuery,但想知道是否有办法让它直接在 d0 上工作。
谢谢。
不,您不能以这种方式将 dbGetQuery
与 dplyr
一起使用,它仅适用于 DBIConnection
。
此外,您的第一个查询是多余的,d0
已经表示 USArrests
数据,第二个查询是无意义的。
dplyr
使用的方法有点不同,它使用 dplyr
动词并创建一个 SQL 查询:
d0 %>% filter(Murder > 10) %>% show_query()
好的,查看 str
有助于揭示如何使用以下命令访问所需的元素:
con <- d0$src$con
db_name <- db_list_tables(con)[1]
一方面,tbl()
函数是一个 SQL 类型的 SELECT * FROM Table
语句,它在 DBMS 上工作并从数据库服务器检索数据,它需要一个 pull 函数喜欢 collect()
。另一方面,函数 dbGetQuery()
使用 SQL 查询将数据检索到 R 会话中。两者都需要与服务器的连接和语句,但第一个使用 SQL 翻译创建语句,另一个是编写 SQL 查询的用户。
为了说明,我将在 postgreSQL DBMS 中使用时间 table tmp
:
# Example on postgreSQL
library(tidyverse)
library(dbplyr)
library(RPostgreSQL)
library(DBI) # This is loaded with RPostgreSQL package
con <- dbConnect(PostgreSQL(),
dbname="test",
host="localhost",
port=5432,
user="user",
password="pass")
到 PostgreSQL 服务器的虚拟数据
date <- data_frame(Col1 = c("20180212", "20180213"),
Col2 = c("A", "B"))
dbWriteTable(con, "tmp", date, temporary = TRUE)
具有tbl()
功能
tbl(con, "tmp") %>% show_query()
#><SQL>
#>SELECT *
#>FROM "tmp"
tbl(con, "tmp") %>%
mutate(date = to_date(Col1, "YYYYMMDD")) %>%
show_query()
#><SQL>
#>SELECT "row.names", "Col1", "Col2", TO_DATE("Col1", 'YYYYMMDD') AS "date"
#>FROM "tmp"
tbl(con, "tmp") %>%
mutate(date = to_date(Col1, "YYYYMMDD")) %>% #this works on DBMS
collect() %>% #This retrive to R session
str()
#>Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 3 variables:
#> $ row.names: chr "1" "2"
#> $ Col1 : chr "20180212" "20180213"
#> $ Col2 : chr "A" "B"
#> $ date : Date, format: "2018-02-12" "2018-02-13"
具有dbGetQuery()
功能
dbGetQuery(con, "SELECT * FROM tmp") %>%
str()
#>'data.frame': 2 obs. of 3 variables:
#> $ row.names: chr "1" "2"
#> $ Col1 : chr "20180212" "20180213"
#> $ Col2 : chr "A" "B"
dbGetQuery(con, "SELECT * FROM tmp") %>%
mutate(date = as.Date(Col1, format = "%Y%m%d")) %>% #This works on R session
str()
#>'data.frame': 2 obs. of 4 variables:
#> $ row.names: chr "1" "2"
#> $ Col1 : chr "20180212" "20180213"
#> $ Col2 : chr "A" "B"
#> $ date : Date, format: "2018-02-12" "2018-02-13"
结论
tbl()
函数是 R 编程中 dbGetQuery()
的高级函数。考虑重新设计您的代码链,了解这两个函数之间的差异以及它们的最佳用途。
示例代码:
library(DBI)
library(RSQLite)
# will require more details (like user, password, host, port, etc.)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
data(USArrests)
dbWriteTable(con, "USArrests", USArrests)
dbListTables(con)
d0 <- tbl(con, "USArrests")
dbGetQuery(d0, "select * from USArrests")
dbGetQuery(d0, "select * from d0")
哪个returns:
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘dbGetQuery’ for signature ‘"tbl_dbi", "character"’
显然我可以在 con 上使用 dbGetQuery,但想知道是否有办法让它直接在 d0 上工作。
谢谢。
不,您不能以这种方式将 dbGetQuery
与 dplyr
一起使用,它仅适用于 DBIConnection
。
此外,您的第一个查询是多余的,d0
已经表示 USArrests
数据,第二个查询是无意义的。
dplyr
使用的方法有点不同,它使用 dplyr
动词并创建一个 SQL 查询:
d0 %>% filter(Murder > 10) %>% show_query()
好的,查看 str
有助于揭示如何使用以下命令访问所需的元素:
con <- d0$src$con
db_name <- db_list_tables(con)[1]
一方面,tbl()
函数是一个 SQL 类型的 SELECT * FROM Table
语句,它在 DBMS 上工作并从数据库服务器检索数据,它需要一个 pull 函数喜欢 collect()
。另一方面,函数 dbGetQuery()
使用 SQL 查询将数据检索到 R 会话中。两者都需要与服务器的连接和语句,但第一个使用 SQL 翻译创建语句,另一个是编写 SQL 查询的用户。
为了说明,我将在 postgreSQL DBMS 中使用时间 table tmp
:
# Example on postgreSQL
library(tidyverse)
library(dbplyr)
library(RPostgreSQL)
library(DBI) # This is loaded with RPostgreSQL package
con <- dbConnect(PostgreSQL(),
dbname="test",
host="localhost",
port=5432,
user="user",
password="pass")
到 PostgreSQL 服务器的虚拟数据
date <- data_frame(Col1 = c("20180212", "20180213"),
Col2 = c("A", "B"))
dbWriteTable(con, "tmp", date, temporary = TRUE)
具有tbl()
功能
tbl(con, "tmp") %>% show_query()
#><SQL>
#>SELECT *
#>FROM "tmp"
tbl(con, "tmp") %>%
mutate(date = to_date(Col1, "YYYYMMDD")) %>%
show_query()
#><SQL>
#>SELECT "row.names", "Col1", "Col2", TO_DATE("Col1", 'YYYYMMDD') AS "date"
#>FROM "tmp"
tbl(con, "tmp") %>%
mutate(date = to_date(Col1, "YYYYMMDD")) %>% #this works on DBMS
collect() %>% #This retrive to R session
str()
#>Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 3 variables:
#> $ row.names: chr "1" "2"
#> $ Col1 : chr "20180212" "20180213"
#> $ Col2 : chr "A" "B"
#> $ date : Date, format: "2018-02-12" "2018-02-13"
具有dbGetQuery()
功能
dbGetQuery(con, "SELECT * FROM tmp") %>%
str()
#>'data.frame': 2 obs. of 3 variables:
#> $ row.names: chr "1" "2"
#> $ Col1 : chr "20180212" "20180213"
#> $ Col2 : chr "A" "B"
dbGetQuery(con, "SELECT * FROM tmp") %>%
mutate(date = as.Date(Col1, format = "%Y%m%d")) %>% #This works on R session
str()
#>'data.frame': 2 obs. of 4 variables:
#> $ row.names: chr "1" "2"
#> $ Col1 : chr "20180212" "20180213"
#> $ Col2 : chr "A" "B"
#> $ date : Date, format: "2018-02-12" "2018-02-13"
结论
tbl()
函数是 R 编程中 dbGetQuery()
的高级函数。考虑重新设计您的代码链,了解这两个函数之间的差异以及它们的最佳用途。