我正在通過 R 中的 ODBC 連接連接到 SQL Server 資料庫。我有兩種可能的方法來獲取資料,并試圖確定哪種方法更有效。Shiny 儀表板需要資料,因此需要在加載應用程式時提取資料,而不是在用戶使用應用程式時動態查詢。
方法一是使用20多個存盤程序來查詢所有需要的資料并存盤起來以備使用。方法二是逐個查詢所有表。
這是我用來查詢其中一個存盤程序的方法:
get_proc_data <- function(proc_name, url, start_date, end_date){
dbGetQuery(con, paste0(
"EXEC dbo.", proc_name, " ",
"@URL = N'", url, "', ",
"@Startdate = '", start_date, "', ",
"@enddate = '", end_date, "' "
))
}
data <- get_proc_data(proc_name, url, today(), today() %m-% years(5))
但是,每個存盤程序的引數設定都略有不同,因此我必須分別定義它們。
我已經開始實作方法 2,但是遇到了迭代查詢每個表的問題。
# use dplyr create list of table names
db_tables <- dbGetQuery(con, "SELECT * FROM [database_name].INFORMATION_SCHEMA.TABLES;") %>% select(TABLE_NAME)
# use dplyr pull to create list
table_list <- pull(db_tables , TABLE_NAME)
# get a quick look at the first few rows
tbl(con, "[TableName]") %>% head() %>% glimpse()
# iterate through all table names, get the first five rows, and export to .csv
for (table in table_list){
write.csv(
tbl(con, table) %>% head(), str_glue("{getwd()}/00_exports/tables/{table}.csv")
)
}
selected_tables <- db_tables %>% filter(TABLE_NAME == c("TableName1","TableName2"))
最終,這種方法只是為了測驗迭代大約 60 個表并執行所需的功能需要多長時間。我已經嘗試將它放入一個函式中,但無法讓它迭代,同時還提取表的名稱。
方法 1 的優缺點:存盤的程序當前正在為一個用 C 撰寫的指標插件提供動力,并在網頁上顯示指標。這是供內部使用以監控網站性能。但是,存盤程序對我來說并不是全部可見,客戶需要我擴展他們當前的指標。我也沒有可以使用的 DBA 來幫助處理 SQL Server 端,并且撰寫 procs 的人不可用。procs 也使用不同的邏輯,因此連接兩個不同 procs 的結果會給出截然不同的值。例如,根據 proc,每個日期將列出每天的總頁面瀏覽量,或者已經按每周或每月的規模匯總,然后重復列出。因此,加入和分組會導致實際頁面瀏覽量出現嚴重錯誤。
方法 2 的優缺點:我熟悉 dplyr,并且能夠將表連接在一起以提取我需要的資料。但是,我對 SQL 不太熟悉,也沒有任何型別的物體關系圖 (ERD) 可供參考。否則,我將單獨構建每個查詢。
無論哪種方式,我都試圖想出一種方法來繼續使用命名函式、lambda 函式或矢量化方法進行迭代。最好為每個變數命名并適當地分配它們,以便我可以使用 dplyr 執行資料整理。
任何幫助將不勝感激,我對前進的方向感到不知所措。我研究了 R 中的 Python 串列理解等價物,但無法讓 R 中的函式執行類似的操作。
> db_table_head_to_csv <- function(table) {
write.csv(
tbl(con, table) %>% head(), str_glue("{getwd()}/00_exports/bibliometrics_tables/{table}.csv")
)
}
>
> bibliometrics_tables %>% db_table_head_to_csv()
Error in UseMethod("as.sql") :
no applicable method for 'as.sql' applied to an object of class "data.frame"
uj5u.com熱心網友回復:
lapply考慮使用(與 Python 的串列/字典理解對應)將所有表資料存盤在命名串列(與 Python 字典對應)中。如果你使用它的兄弟,sapply傳入的字符向量將作為元素的名稱回傳:
# RETURN VECTOR OF TABLE NAMES
db_tables <- dbGetQuery(
con, "SELECT [TABLE_NAME] FROM [database_name].INFORMATION_SCHEMA.TABLES"
)$TABLE_NAME
# RETURN NAMED LIST OF DATA FRAMES FOR EACH DB TABLE
df_list <- sapply(db_tables, function(t) dbReadTable(conn, t), simplify = FALSE)
您可以將lambda函式擴展為多個步驟,例如write.csv或使用定義的方法。只需確保將return資料框作為最后一行。下面使用|>基礎 R 4.1.0 中的新管道:
db_table_head_to_csv <- function(table) {
head_df <- dbReadTable(con, table) |> head()
write.csv(
head_df,
file.path(
"00_exports", "bibliometrics_tables", paste0(table, ".csv")
)
)
return(head_df)
}
df_list <- sapply(db_tables, db_table_head_to_csv, simplify = FALSE)
如果存盤在串列中并且可以使用$或[[按名稱提取,則不會丟失資料框物件的功能:
# EXTRACT SPECIFIC ELEMENT
head(df_list$table_1)
tail(df_list[["table_2"]])
summary(df_list$`table_3`)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/432426.html
下一篇:按日期查找活躍客戶
