ODBC/DBI в R не будет записывать в таблицу со схемой не по умолчанию в R

Проблема

При попытке записи в таблицу со схемой, отличной от схемы по умолчанию, dbWriteTable в DBI пакета записывает в default.non-default.tablename, а не в non-default.tablename. Я знаю, что non-default.tablename существует, потому что он отображается в моей базе данных SSMS.

Воспроизводимый пример / Что я пробовал

Создайте эту таблицу в SQL Server с нестандартной схемой «гость». Я помещаю его в базу данных под названием «SAM»:

CREATE TABLE guest.MikeTestTable(
[a] [float] NULL,
[b] [float] NULL,
[c] [varchar](255) NULL)

#Create a df to insert into guest.MikeTestTable
df <- data.frame(a = c(10, 20, 30),
                 b = c(20, 40, 60),
                 c = c("oneT", "twoT", "threeT"))

#Create a connection:
con <- DBI::dbConnect(odbc::odbc(),
             .connection_string = "Driver={SQL Server};
                                   server=localhost;
                                   database=SAM;
                                   trustedConnection=true;")

#Try to write contents of df to the table using `dbWriteTable`
DBI::dbWriteTable(conn = con,
                  name = "guest.MikeTestTable",
                  value = df,
                  append = TRUE)

#Create a query to read the data from `"guest.MikeTestTable"`:
q <- "SELECT [a]
  ,[b]
  ,[c]
  FROM guest.MikeTestTable"

##Read the table into R to show that nothing actually got written to the 
##table but that it recognizes `guest.MikeTestTable` does exist:
DBI::dbGetQuery(con, q)

[1] a b c
<0 rows> (or 0-length row.names)

Я подумал, что это странный результат, поэтому я открыл свою SSMS, и о чудо, таблица dbo.guest.MikeTestTable была создана. Любая помощь приветствуется.


person user111417    schedule 27.07.2017    source источник
comment
Попробуйте следующее: dbWriteTable(con, c("schema_name","table_name"), df, append = TRUE)   -  person Parfait    schedule 27.07.2017
comment
Спасибо за совет. Попытка dbWriteTable(con, c("guest", "MikeTestTable"), df, append = TRUE) возвращает ошибку: Error: length(name) == 1 is not TRUE   -  person user111417    schedule 27.07.2017
comment
Ну, похоже, это работает только с драйвером Postgres. Попробуйте использовать пакет RODBC. Я вижу, что кто-то пропинговал авторов DBI. Это ты?   -  person Parfait    schedule 27.07.2017
comment
Мы не хотим использовать пакет RODBC, потому что он плохо работает со сборками Travis на Linux и Mac. Я сделал несколько замечаний в пинге авторов DBI.   -  person user111417    schedule 27.07.2017


Ответы (2)


Выпуск CRAN на прошлой неделе (связанный с проблемой @user111417, на которую ссылается) решает эту проблему с помощью новой функции DBI::Id(), где имена схемы и таблицы являются отдельными и явными. Вот пример.

library(magrittr)
table_id <- DBI::Id(
  schema  = "schema_1",
  table   = "car"
)

ds <- mtcars %>% 
  tibble::rownames_to_column("car")

# Create the Table
channel <- DBI::dbConnect(
  drv   = odbc::odbc(),
  dsn   = "cdw_cache"
)
result <- DBI::dbWriteTable(
  conn        = channel,
  name        = table_id,
  value       = ds,
  overwrite   = T,
  append      = F
)

DBI::dbGetQuery(channel, "SELECT COUNT(*) FROM schema_1.car")
# Produces `1 32`

DBI::dbExistsTable(channel, table_id)
# Produces: [1] TRUE

DBI::dbDisconnect(channel)

(Спасибо Дэниелу Вуду за помощь в https://github.com/r-dbi/odbc/issues/191.)

person wibeasley    schedule 16.06.2018

См. здесь для ответа

person user111417    schedule 22.08.2017