简体   繁体   English

是否可以直接在类tbl_sql(或tbl_dbi)上运行SQL查询?

[英]Is it possible to run SQL query directly on class tbl_sql (or tbl_dbi)?

Example code: 示例代码:

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")

Which returns: 哪个返回:

Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘dbGetQuery’ for signature ‘"tbl_dbi", "character"’

Obviously I could just use dbGetQuery on con, but was wondering if there is a way to have it work on d0 directly. 显然,我可以只在con上使用dbGetQuery,但是想知道是否有一种方法可以直接在d0上工作。

Thanks. 谢谢。

On the one hand, is the tbl() function which is a SQL statement of type SELECT * FROM Table this works over DBMS and to retrieve data from database server it need a pull function like collect() . 一方面,它是tbl()函数,它是SELECT * FROM Table类型的SQL语句,可在DBMS上运行,并且要从数据库服务器检索数据,需要像collect()这样的pull函数。 On the other hand, is the function dbGetQuery() which retrieves the data into R session using a SQL query. 另一方面,是函数dbGetQuery() ,该函数使用SQL查询将数据检索到R会话中。 Both requires a connection to server and a statement, but the first create the statement using SQL translations and the other is the user which write the SQL query. 两者都需要连接到服务器和一条语句,但是第一个使用SQL转换创建该语句,另一个是编写SQL查询的用户。

To illustrate I will use a temporal table tmp in a postgreSQL DBMS: 为了说明,我将在postgreSQL DBMS中使用临时表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")

Dummy data to PostgreSQL server 虚拟数据到PostgreSQL服务器

date <- data_frame(Col1 = c("20180212", "20180213"),
                   Col2 = c("A", "B"))
dbWriteTable(con, "tmp", date, temporary = TRUE)

With tbl() function 使用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"

With dbGetQuery() function 使用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"

Conclusion 结论

tbl() function is a high level over dbGetQuery() in R-programming. 在R编程中, tbl()函数比dbGetQuery()高。 Consider to re-design your code chain understanding the differences between both functions and best uses for these. 考虑重新设计您的代码链,以了解这两个功能之间的差异以及这些功能的最佳用途。

No, you can't use dbGetQuery with dplyr in this way, it only work with DBIConnection . 不,您不能以这种方式将dbGetQuerydplyr一起使用,它仅与DBIConnection一起DBIConnection

Also, your first query is redundany, d0 already represent the USArrests data and second query is nonsense. 同样,您的第一个查询是多余的, d0已经表示USArrests数据,第二个查询是废话。

dplyr is using a bit different approach, it uses dplyr verbs and creating an SQL query: dplyr使用的方法dplyr不同,它使用dplyr动词并创建一个SQL查询:

d0 %>% filter(Murder > 10) %>% show_query()

ok, looking at the str helped reveal how to access the needed elements using the following commands: 好的,看一下str有助于揭示如何使用以下命令访问所需的元素:

  con <- d0$src$con
  db_name <- db_list_tables(con)[1]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM