Подтвердить что ты не робот

Как подключить R с базой данных Access в 64-битном окне?

Когда я попытался подключить R к базе данных Access, я получаю сообщение об ошибке

odbcConnectAccess is only usable with 32-bit Windows

Есть ли у кого-нибудь идея, как это решить?

library(RODBC) 
mdbConnect<-odbcConnectAccess("D:/SampleDB1/sampleDB1.mdb")
4b9b3361

Ответ 1

Используйте odbcDriverConnect вместо этого. Если у вас установлено 64-битное R, вам, возможно, придется использовать 32-разрядную сборку R.

odbcDriverConnect("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:/SampleDB1/sampleDB1.mdb")

Ответ 2

Вот одна функция, которая будет передавать данные из 32-битного доступа к 64-битовому R без необходимости сохранять файлы. Функция строит строку выражения, которая передается во второй 32-разрядный сеанс; данные затем возвращаются в исходный сеанс с использованием пакета сокетов (svSocket). Следует отметить, что сервер сокетов сохраняет данные доступа в глобальной среде, поэтому второй параметр используется для определения вывода вместо использования "< -" для сохранения вывода.

access_query_32 <- function(db_table = "qryData_RM", table_out = "data_access") {
  library(svSocket)

  # variables to make values uniform
  sock_port <- 8642L
  sock_con <- "sv_con"
  ODBC_con <- "a32_con"
  db_path <- "~/path/to/access.accdb"

  if (file.exists(db_path)) {

    # build ODBC string
    ODBC_str <- local({
      s <- list()
      s$path <- paste0("DBQ=", gsub("(/|\\\\)+", "/", path.expand(db_path)))
      s$driver <- "Driver={Microsoft Access Driver (*.mdb, *.accdb)}"
      s$threads <- "Threads=4"
      s$buffer <- "MaxBufferSize=4096"
      s$timeout <- "PageTimeout=5"
      paste(s, collapse=";")
    })

    # start socket server to transfer data to 32 bit session
    startSocketServer(port=sock_port, server.name="access_query_32", local=TRUE)

    # build expression to pass to 32 bit R session
    expr <- "library(svSocket)"
    expr <- c(expr, "library(RODBC)")
    expr <- c(expr, sprintf("%s <- odbcDriverConnect('%s')", ODBC_con, ODBC_str))
    expr <- c(expr, sprintf("if('%1$s' %%in%% sqlTables(%2$s)$TABLE_NAME) {%1$s <- sqlFetch(%2$s, '%1$s')} else {%1$s <- 'table %1$s not found'}", db_table, ODBC_con))
    expr <- c(expr, sprintf("%s <- socketConnection(port=%i)", sock_con, sock_port))
    expr <- c(expr, sprintf("evalServer(%s, %s, %s)", sock_con, table_out, db_table))
    expr <- c(expr, "odbcCloseAll()")
    expr <- c(expr, sprintf("close(%s)", sock_con))
    expr <- paste(expr, collapse=";")

    # launch 32 bit R session and run expressions
    prog <- file.path(R.home(), "bin", "i386", "Rscript.exe")
    system2(prog, args=c("-e", shQuote(expr)), stdout=NULL, wait=TRUE, invisible=TRUE)

    # stop socket server
    stopSocketServer(port=sock_port)

    # display table fields
    message("retrieved: ", table_out, " - ", paste(colnames(get(table_out)), collapse=", "))
  } else {
    warning("database not found: ", db_path)
  }
}

Иногда эта функция возвращает ошибку, но она не влияет на извлечение данных и, по-видимому, возникает из-за закрытия подключения к серверу сокетов.

Вероятно, есть возможности для улучшения, но это обеспечивает простой и быстрый способ извлечения данных в R из 32-битного доступа.

Ответ 3

Не удалось с данными ответами, но вот шаг за шагом подход, который в конечном итоге помогло. У Windows 8 на 64 бит. При установке 64 и 32 бит R. Мой доступ 32 бит.

Шаги для использования, предполагающие 32-битный доступ к окнам 8

  • Выберите 32 бит R (это просто настройка в студии R)
  • поиск по окнам для настройки источников данных ODBC (32 бит)
  • Перейдите в Системный DSN > Добавить
  • Выберите "Драйвер" для Microsoft Access (*.mdb) > "Готово"
  • Имя источника данных: ProjecnameAcc
  • Описание: ProjectnameAcc
  • Обязательно выберите базу данных > OK

Теперь я могу запустить код, который мне понравился

channel <- odbcConnect("ProjectnameAcc")
Table1Dat <- sqlFetch(channel, "Table1")

Ответ 4

Я столкнулся с этим SO, когда столкнулся с подобной проблемой, и на данный момент у нас есть по крайней мере еще один вариант с чрезвычайно гибкой библиотекой odbc.

Здесь важно отметить: драйвер ODBC для MS Access не является частью установки MS Office по умолчанию, поэтому вам придется загрузить соответствующий драйвер от Microsoft (Microsoft Access Database Engine 2016, распространяемый в моем случае) и обязательно загрузить соответствующую битность (например, AccessDatabaseEngine_X64.exe). После того, как оно было загружено, оно должно автоматически отображаться в вашей служебной программе Windows ODBC Data Sources (64-bit) или вы можете подтвердить это в сеансе R с помощью функции odbcListDrivers.

library(odbc)

# run if you want to see what drivers odbc has available
# odbcListDrivers()

# full file path to Access DB
file_path <- "~/some_access_file.accdb"

# pass MS Access file path to connection string
accdb_con <- dbConnect(drv = odbc(), .connection_string = paste0("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=",file_path,";"))

Ответ 5

Используя советы других, здесь приведен пример получения 32-разрядных данных Access в 64-разрядный R, которые вы можете записать в script, так что вам не нужно выполнять эти шаги вручную. Для этого вам необходимо иметь 32-разрядный R, и этот script предполагает местоположение по умолчанию для 32-битного R, поэтому при необходимости отрегулируйте его.

Первая часть кода входит в ваш основной script, вторая часть кода - это все содержимое небольшого файла R script, который вы создаете и вызывается из основного script, эта комбинация извлекает и сохраняет и затем загружает данные из базы данных доступа без остановки.

Здесь бит, который идет в моем главном script, запускается из 64 бит R

##  Lots of script above here
## set the 32-bit script location
pathIn32BitRScript <- "C:/R_Code/GetAccessDbTables.R"
## run the 32 bit script
system(paste0(Sys.getenv("R_HOME"), "/bin/i386/Rscript.exe ",pathIn32BitRScript))
## Set the path for loading the rda files created from the little script 
pathOutUpAccdb <- "C/R_Work/"
## load the tables just created from that script
load(paste0(pathOutUpAccdb,"pots.rda"))
load(paste0(pathOutUpAccdb,"pans.rda"))
## Lots of script below here

Здесь бит, который является отдельным script, называется GetAccessTables.R

library(RODBC).    
## set the database path
inCopyDbPath <- "C:/Projects/MyDatabase.accdb"
## connect to the database
conAccdb <- odbcConnectAccess2007(inCopyDbPath) 

## Fetch the tables from the database. Modify the as-is and string settings as desired
pots <- sqlFetch (conAccdb,"tbl_Pots",as.is=FALSE, stringsAsFactors = FALSE)
pans <- sqlFetch(conAccdb,"tbl_Pans",as.is=FALSE, stringsAsFactors = FALSE)
## Save the tables
save(pots, file = "C/R_Work/pots.rda")
save(pans, file = "C:/R_Work/pans.rda")
close(conAccdb)

Ответ 6

Функция с помощью manotheshark выше очень полезна, но я хотел использовать SQL-запрос, а не имя таблицы, для доступа к базе данных, а также для передачи имени базы данных в качестве параметра, поскольку я обычно работаю с рядом Access базы данных. Вот модифицированная версия:

access_sql_32 <- function(db_sql = NULL, table_out = NULL, db_path = NULL) {
  library(svSocket)

  # variables to make values uniform
  sock_port <- 8642L
  sock_con <- "sv_con"
  ODBC_con <- "a32_con"

  if (file.exists(db_path)) {

    # build ODBC string
    ODBC_str <- local({
      s <- list()
      s$path    <- paste0("DBQ=", gsub("(/|\\\\)+", "/", path.expand(db_path)))
      s$driver  <- "Driver={Microsoft Access Driver (*.mdb, *.accdb)}"
      s$threads <- "Threads=4"
      s$buffer  <- "MaxBufferSize=4096"
      s$timeout <- "PageTimeout=5"
      paste(s, collapse=";")
    })

    # start socket server to transfer data to 32 bit session
    startSocketServer(port=sock_port, server.name="access_query_32", local=TRUE)

    # build expression to pass to 32 bit R session
    expr <- "library(svSocket)"
    expr <- c(expr, "library(RODBC)")
    expr <- c(expr, sprintf("%s <- odbcDriverConnect('%s')", ODBC_con, ODBC_str))
    expr <- c(expr, sprintf("%1$s <- sqlQuery(%3$s, \"%2$s\")", table_out, db_sql, ODBC_con))
    expr <- c(expr, sprintf("%s <- socketConnection(port=%i)", sock_con, sock_port))
    expr <- c(expr, sprintf("evalServer(%s, %s, %s)", sock_con, table_out, table_out))
    expr <- c(expr, "odbcCloseAll()")
    expr <- c(expr, sprintf("close(%s)", sock_con))
    expr <- paste(expr, collapse=";")

    # launch 32 bit R session and run the expression we built
    prog <- file.path(R.home(), "bin", "i386", "Rscript.exe")
    system2(prog, args=c("-e", shQuote(expr)), stdout=NULL, wait=TRUE, invisible=TRUE)

    # stop socket server
    stopSocketServer(port=sock_port)

    # display table fields
    message("Retrieved: ", table_out, " - ", paste(colnames(get(table_out)), collapse=", "))
  } else {
    warning("database not found: ", db_path)
  }
}

У меня также возникли трудности с разработкой способа вызова функции manotheshark, и потребовалось некоторое обсуждение в документации пакета svSocket, чтобы понять, что вызывающему script необходимо создать экземпляр объекта, в котором данные будут возвращены, а затем передать его NAME (не сам объект) в параметре table_out. Вот пример R- script, который вызывает мою измененную версию:

source("scripts/access_sql_32.R")
spnames <- data.frame()
# NB. use single quotes for any embedded strings in the SQL
sql <- "SELECT name as species FROM checklist 
        WHERE rank = 'species' ORDER BY name"
access_sql_32(sql, "spnames", "X:/path/path/mydata.accdb")

Это работает, но имеет ограничения.

Во-первых, избегайте любых расширений Microsoft Access SQL. Например, если вы используете построитель Query Access, он часто вводит имена полей, например [TABLE_NAME]![FIELD_NAME]. Это не сработает. Также Access позволяет нестандартные имена полей начинаться с цифры типа "10kmSq" и позволяет использовать их в SQL, например SELECT [10kmSq] FROM .... Это тоже не сработает. Если в синтаксисе SQL имеется ошибка, возвращаемая переменная будет содержать сообщение об ошибке.

Во-вторых, количество данных, которые вы можете вернуть, ограничено до 64Kb. Если вы попытаетесь запустить SQL, который слишком много возвращается, 32-разрядный сеанс не заканчивается и script зависает.

Ответ 7

У меня сработало следующее решение: найдено на чтение-данных-из-32-битного-доступа-db-using-64-bit-R В нем говорится об установке 64-разрядного ядра базы данных от: microsoft'

Затем: найдите и запустите "ODBC-источники данных (64-битные)".

  1. На вкладке "Пользователь-DSN" нажмите "Добавить"
  2. Выберите "Драйвер Microsoft Access" и сохраните
  3. Дайте вашему новому источнику данных имя (вы будете использовать это имя при подключении к базе данных позже)
  4. Нажмите "Выбрать": выберите каталог, в котором существуют базы данных доступа, и сохраните

.Тогда в R:

library(RODBC)
dcon <- dbConnect(odbc::odbc(), "name-you-gave-to-your-datasource-in-3")

Ответ 8

Я использую Windows 10 x64, Office 365 x64 (не уверен, что это актуально) и R 64-bit. Мне не нужно было переключаться на 32-битную R.

В моем случае я заработал, установив 64-разрядную версию распространяемого компонента Microsoft Access Database Engine 2016, а затем предоставив свою учетную запись, которая запускается как rsession.exe, Полный доступ разрешения для раздела реестра HKEY_LOCAL_MACHINE\SOFTWARE\ODBC.

Разрешения на ключ реестра не имеют смысла. Моя учетная запись уже является членом этой группы администраторов ПК, и эта группа уже имеет разрешение Полный доступ для этого ключа.

Команды, которые я использовал:

library("odbc")

accdb_con <- dbConnect(drv = odbc(), .connection_string = paste0("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:/full_path_to_file/buildings.mdb;"))