Как подключить R с базой данных Access в 64-битном окне?
Когда я попытался подключить R к базе данных Access, я получаю сообщение об ошибке
odbcConnectAccess is only usable with 32-bit Windows
Есть ли у кого-нибудь идея, как это решить?
library(RODBC)
mdbConnect<-odbcConnectAccess("D:/SampleDB1/sampleDB1.mdb")
Ответы
Ответ 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-битные)".
- На вкладке "Пользователь-DSN" нажмите "Добавить"
- Выберите "Драйвер Microsoft Access" и сохраните
- Дайте вашему новому источнику данных имя (вы будете использовать это имя при подключении к базе данных позже)
- Нажмите "Выбрать": выберите каталог, в котором существуют базы данных доступа, и сохраните
.Тогда в 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;"))