Comment se connecter à la base de données Access dans une fenêtre 64 bits?
quand j'ai essayé de connecter R avec la base de données D'accès Je reçois une erreur
odbcConnectAccess is only usable with 32-bit Windows
quelqu'un a-t-il une idée pour résoudre ce problème?
library(RODBC)
mdbConnect<-odbcConnectAccess("D:/SampleDB1/sampleDB1.mdb")
6 réponses
Utiliser odbcDriverConnect
à la place. Si vous avez 64-bit R installé, vous pouvez devoir utiliser le 32-bit R construire.
odbcDriverConnect("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:/SampleDB1/sampleDB1.mdb")
Voici une fonction unique qui va transférer des données de l'accès 32 bits à 64 bits R sans avoir à enregistrer des fichiers. La fonction Construit une chaîne d'expression qui est passée à une deuxième session de 32 bits; les données sont ensuite retournées à la session originale en utilisant socket server package (svSocket). Une chose à noter est que le serveur de socket sauve les données d'accès dans l'environnement global ainsi le deuxième paramètre est utilisé pour définir la sortie au lieu d'utiliser "<-" pour sauver le sortie.
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)
}
}
occasionnellement, cette fonction renvoie une erreur, mais elle n'affecte pas la récupération de données et semble résulter de la fermeture de la connexion au serveur socket.
Il y a probablement place à amélioration, mais cela fournit une méthode simple et rapide pour tirer des données dans R à partir d'un accès 32 bits.
N'a pas réussi avec les réponses données, mais voici l'approche étape par étape qui a finalement fait l'affaire pour moi. Windows 8 sur 64 bits. Avec 64 et 32 bits R installés. Mon accès est 32 bits.
les Étapes pour utiliser, en supposant que le 32 bits, Accès sur windows 8
- Sélectionner 32 bits R (c'est juste un réglage dans la R studio)
- recherche sur windows pour configurer des sources de données ODBC (32 bits)
- Aller à la DSN Système>Ajouter
- choisir Driver do Microsoft Accès.*( mdb) > Finition
- source des données Nom: ProjecnameAcc
- Description: ProjectnameAcc
- assurez-vous de bien sélectionner la base de données > OK
maintenant je peux lancer le code que j'aime
channel <- odbcConnect("ProjectnameAcc")
Table1Dat <- sqlFetch(channel, "Table1")
en utilisant les conseils d'autres personnes, voici un exemple explicite de l'obtention de données d'accès 32-bit dans 64-bit R que vous pouvez écrire dans un script de sorte que vous n'avez pas besoin de faire les étapes manuellement. Vous avez besoin d'avoir 32-bit r disponible sur votre machine pour que cela fonctionne, et ce script suppose un emplacement par défaut pour le 32 bit R, donc ajustez si nécessaire.
la première partie de code va dans votre script principal, la deuxième partie de code est le contenu entier d'un petit fichier de script R que vous créez et est appelé à partir du script principal, Cette combinaison extrait et sauvegarde puis charge les données de la base de données d'accès sans avoir à s'arrêter.
voici le morceau qui va dans mon script principal, ceci est exécuté à partir de 64 bit 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
voici le morceau qui est le script séparé appelé 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)
la fonction de manotheshark ci-dessus est très utile, mais je voulais utiliser une requête SQL, plutôt qu'un nom de table, pour accéder à la base de données et aussi pour passer le nom de la base de données comme paramètre puisque je travaille généralement avec un certain nombre de bases de données D'accès. Voici une version modifiée:
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)
}
}
j'ai aussi eu quelques difficultés à trouver comment appeler la fonction de manotheshark et il a fallu fouiller dans la documentation du paquet svSocket pour comprendre que le script d'appel devait instanciez l'objet dans lequel les données seront retournées et ensuite passez son nom (pas l'objet lui-même) dans le paramètre table_out. Voici un exemple de script R qui appelle ma version modifiée:
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")
cela fonctionne, mais a des limites.
tout d'abord, évitez toute extension SQL Microsoft Access. Par exemple, si vous utilisez Access Query builder, il insérera souvent des noms de champs comme [TABLE_NAME]![FIELD_NAME]
. Ces ne fonctionnera pas. L'accès permet également des noms de champ non standard qui commencent avec un chiffre comme "10kmSq" et vous permet de les utiliser en SQL comme SELECT [10kmSq] FROM ...
. Ce aussi de ne pas travailler. S'il y a une erreur dans la syntaxe SQL, la variable de retour contiendra un message d'erreur.
Deuxièmement, la quantité de données que vous pouvez retourner semble être limitée à 64 ko. Si vous essayez D'exécuter SQL qui retourne trop, la session 32 bits ne se termine pas et le script est suspendu.
je suis tombé sur ce si en rencontrant un problème similaire et à ce point nous avons au moins une option de plus avec la bibliothèque odbc extrêmement flexible.
une note importante ici cependant: le pilote MS Access ODBC ne fait pas partie d'une installation MS Office par défaut donc vous devrez télécharger le pilote approprié de Microsoft (Microsoft Access Database Engine 2016 redistribuable dans mon cas) et être sûr de télécharger le bitness approprié (par exemple AccessDatabaseEngine_X64.EXE.) Une fois que cela a été téléchargé, il devrait apparaître automatiquement dans votre Windows ODBC Source de données (64-bit) utilitaire ou vous pouvez confirmer à l'intérieur d'une session R avec la fonction 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,";"))