RをAccessデータベースに接続しようとするとエラーが発生します
odbcConnectAccess is only usable with 32-bit Windows
誰もこれを解決する方法を知っていますか?
library(RODBC)
mdbConnect<-odbcConnectAccess("D:/SampleDB1/sampleDB1.mdb")
代わりにodbcDriverConnect
を使用してください。 64ビットRがインストールされている場合は、32ビットRビルドを使用する必要があります。
odbcDriverConnect("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:/SampleDB1/sampleDB1.mdb")
ファイルを保存せずに32ビットアクセスから64ビットRにデータを転送する単一の関数を次に示します。この関数は、2番目の32ビットセッションに渡される式文字列を作成します。その後、データはソケットサーバーパッケージ(svSocket)を使用して元のセッションに返されます。注意すべきことの1つは、ソケットサーバーがアクセスデータをグローバル環境に保存するため、出力を保存するために「<-」を使用する代わりに2番目のパラメーターを使用して出力を定義することです。
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)
}
}
この関数はエラーを返すことがありますが、データの取得には影響せず、ソケットサーバー接続を閉じた結果として表示されます。
改善の余地はありそうですが、これにより、32ビットアクセスからRにデータをプルする簡単で迅速な方法が提供されます。
与えられた答えでは成功しませんでしたが、最終的に私のためにトリックを行ったステップバイステップのアプローチがあります。 64ビットでWindows 8を使用します。 64ビットおよび32ビットRがインストールされている。私のアクセスは32ビットです。
これで、気に入ったコードを実行できました
channel <- odbcConnect("ProjectnameAcc")
Table1Dat <- sqlFetch(channel, "Table1")
私はこれに遭遇しましたSO同様の問題に遭遇したとき、この時点で、非常に柔軟なodbcライブラリに少なくとも1つのオプションがあります。
ただし、重要な注意事項:MS Access ODBCドライバーはデフォルトのMS Officeインストールの一部ではないため、Microsoftから適切なドライバーをダウンロードする必要があります(私の場合はMicrosoft Access Database Engine 2016再頒布可能) )そして、適切なbitness(例:AccessDatabaseEngine_X64.exe)をダウンロードしてください。ダウンロードされると、Windows ODBC Data Sources(64-bit)ユーティリティに自動的に表示されるはずです。 odbcListDrivers関数を使用してRセッション内で確認します。
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,";"))
他の人からのアドバイスを使用して、手動で手順を実行する必要がないように、スクリプトに書き込むことができる64ビットRに32ビットAccessデータを取得する明示的な例を次に示します。これを実行するには、マシンで32ビットRを使用可能にする必要があり、このスクリプトは32ビットRのデフォルトの場所を想定しているため、必要に応じて調整します。
最初のコード部分はメインスクリプトに入り、2番目のコード部分は作成した小さなRスクリプトファイルの内容全体であり、メインスクリプトから呼び出されます。この組み合わせは、停止する必要があります。
ここに私のメインスクリプトにあるビットがあります、これは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
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)
次のソリューションは私のために働いた: reading-data-from-32-bit-access-db-using-64-bit-R にあります64ビットデータベースエンジンをインストールするように言います:- Microsoft `
次に、「ODBCデータソース(64ビット)」を見つけて実行します。
次に、Rで:
library(RODBC)
dcon <- dbConnect(odbc::odbc(), "name-you-gave-to-your-datasource-in-3")
上記のmanothesharkの機能は非常に便利ですが、多くのAccessデータベースで作業することが多いため、データベースにアクセスし、データベース名をパラメーターとして渡すために、テーブル名ではなくSQLクエリを使用しました。変更されたバージョンは次のとおりです。
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パッケージのドキュメントを掘り下げて、呼び出しスクリプトが、データが返されるオブジェクトをインスタンス化し、そのNAME(オブジェクトではなく)を渡す必要があることを認識しましたそれ自体)table_outパラメーター内。変更したバージョンを呼び出すRスクリプトの例を次に示します。
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拡張機能を使用しないでください。たとえば、Access Query Builderを使用する場合、多くの場合、[TABLE_NAME]![FIELD_NAME]
などのフィールド名が挿入されます。これらは機能しません。また、Accessでは、「10kmSq」などの数字で始まる非標準フィールド名を使用でき、SELECT [10kmSq] FROM ...
などのSQLで使用できます。これも機能しません。 SQL構文にエラーがある場合、戻り変数にはエラーメッセージが含まれます。
第二に、返せるデータの量は64 KBに制限されているようです。大量のSQLを実行しようとすると、32ビットセッションが終了せず、スクリプトがハングします。
Windows 10 x64、Office 365 x64(それが関連するかどうかは不明)、およびR 64ビットを実行しています。 32ビットRに切り替える必要はありませんでした。
私の場合、64ビットバージョンの Microsoft Access Database Engine 2016 Redistributable をインストールしてから、rsession.exeを実行する独自のアカウントHKEY_LOCAL_MACHINE\SOFTWARE\ODBC
レジストリキーに対するフルコントロール権限。
レジストリキーのアクセス許可は意味がありません。私のアカウントはすでにこのPCのAdministratorsグループのメンバーであり、そのグループにはすでにFull Controlそのキーの許可。
私が使用したコマンド:
library("odbc")
accdb_con <- dbConnect(drv = odbc(), .connection_string = paste0("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:/full_path_to_file/buildings.mdb;"))