Python和MS Access VBA之间的OLEDB/ODBC相反操作

3

尊敬的高级程序员们:

如果这似乎是一个老套的Python 32位/64位 ODBC/OLEDB Windows问题,请原谅我,但我已经在论坛中搜索过了,却找不到解决我的问题的原因。

基本上,我首先尝试使用pypyodbc模块通过ODBC连接一个非常简单的Python脚本,然后再尝试使用adodbapi模块通过OLEDB连接到一个MS Access 2010 .accdb数据库。然而,对于OLEDB,我始终会收到“提供程序未找到。可能未正确安装”错误。对于ODBC,我始终收到“未找到数据源名称并且未指定默认驱动程序”的错误。

然而,深入挖掘之后,出现了一些引人注目的事情。在Python中,JET.OLEDB.4.0适用于.mdb文件,但不适用于.accdb文件。然而,当我运行一个Access VBA ADODB连接时,完全相反的情况发生了!

我的环境包括:

  • Python3.4 -32位
  • pywin32-219(使用后安装)
  • Microsoft Office 2010 64位
  • Windows 7

是的,我下载并成功安装了AccessDatabaseEngine_x64.exe。是的,我将ODBC数据源指向了%Win%/SysWOW64。是的,我在前面提到的文件夹中的odbcad32.exe中看到了mdb和accdb的Access驱动程序和数据源。是的,我在regedit中看到了Access(*mdb)和Access(*mdb,*accdb)数据源以及Access驱动程序的注册表键。是的,我重新启动并关闭/开启了我的机器。

OLEDB
以下是我的连接字符串,返回“未找到提供程序错误...”:

import adodbapi
databasename = 'D:\directorypath\DatabaseName.accdb'  
constr = 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=%s'  % databasename 
db = adodbapi.connect(constr)

令人惊讶的是,以下连接字符串可以完美地工作,但只适用于 .mdb 文件:

import adodbapi
databasename = 'D:\otherdirectorypath\OtherDatabaseName.mdb' 
constr = 'Provider=Microsoft.JET.OLEDB.4.0;Data Source=%s'  % databasename 
db = adodbapi.connect(constr)


ODBC
以下是我的连接字符串,返回“找不到数据源名称…”错误:

import pypyodbc
databasename = 'D:\directorypath\DatabaseName.accdb'
constr = 'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;'  % databasename
db = pypyodbc.connect(constr)

和上面一样,以下代码的表现很理想,但只适用于 .mdb 文件:

import pypyodbc
databasename = 'D:\otherdirectorypath\OtherDatabaseName.mdb'
constr = 'DRIVER={Microsoft Access Driver (*.mdb)};DBQ=%s;'  % databasename
db = pypyodbc.connect(constr)


Access VBA
有趣的是,在一个Access VBA模块中(当然包括ActiveX数据对象库引用),使用相同的连接字符串(驱动程序和提供程序),会发生完全相反的情况。

对于.mdb和.accdb文件,代码都可以完美地运行:

Dim constr As String
Dim CN As ADODB.Connection
Dim RS As ADODB.Recordset

constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\databasedirectory\DatabaseName.accdb;Persist Security Info=False"

' OR constr = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=D:\databasedirectory\DatabaseName.accdb;Persist Security Info=False"

Set CN = New ADODB.Connection
CN.Open (constr)

代码返回错误 - '提供程序未找到''指定的驱动程序无法加载'

Dim constr As String
Dim CN As ADODB.Connection
Dim RS As ADODB.Recordset

constr = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=D:\otherdatabasedirectory\OtherDatabaseName.mdb;Persist Security Info=False"

' OR constr = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=D:\otherdatabasedirectory\OtherDatabaseName.mdb;Persist Security Info=False"

Set CN = New ADODB.Connection
CN.Open (constr)

ACE.OLEDB.12.0 VS ACE.OLEDB.14.0
最终,仅在Access VBA中,仅“Provider: Microsoft.ACE.OLEDB.12.0”有效,我认为它对应于MS Access 2007。但是,“Provider: Microsoft.ACE.OLEDB.14.0”不适用于我安装的MS Access 2010。有什么原因吗?
结论
我了解ActiveX库是一种不同于Python模块库的技术,Microsoft不允许同时使用x32位和x64位组件,但为什么我无法获得预期的结果呢?我考虑过AccessDatabaseEngine_x64.exe /passive,但我听说那样会导致Office出现奇怪的结果。我需要安装Python3.4的64位版本吗?请帮忙或建议!谢谢。

2
“同行更高级的程序员们” 好吧,那我就退出了。 - RossC
1个回答

2

简短回答:

是的,如果你安装了64位的Office并且想要用Python操作Access数据库,为了最小化问题,你应该运行64位版本的Python。

详细回答:

旧版的“Jet”引擎/驱动程序和新版的Access Database Engine(也称为“ACE”)引擎/驱动程序是完全独立的实体。

旧版的“Jet”驱动程序...

 ODBC: Driver={Microsoft Access Driver (*.mdb)}
OLEDB: Provider=Microsoft.Jet.OLEDB.4.0  

Windows操作系统已经将...作为其组成部分安装,但它们仅适用于32位应用程序。

你安装了64位的Office,因此你拥有新版“ACE”驱动程序的64位版本...

 ODBC: Driver={Microsoft Access Driver (*.mdb, *.accdb)}
OLEDB: Provider=Microsoft.ACE.OLEDB.12.0  

这些驱动程序仅适用于64位应用程序。

您当前的32位Python环境可以使用Jet驱动程序,但无法使用ACE驱动程序。

您拥有64位版本的Access,因此您的VBA代码正在64位宇宙中运行,它可以使用ACE驱动程序,但无法使用Jet驱动程序。


1
好的,我只能补充说,syswow odbc 仅支持 x32 平台,并且无法与 ACE x64 兼容。用户可以在 odbc syswow 管理器中创建条目,但它们仅适用于 x32。基本问题是,任何 jet/ace ODBC 驱动程序最终都将解析为一个完整的文件路径名,如果您安装了 x64 ace,则只能使用 x64 in-process 软件。虽然 ODBC x32 可以连接到 SQL Server x32/x64,并且“大多数”ODBC驱动程序可以读取accDB文件,但是ACE在"内部"运行,并且就像在一些代码中调用子代一样。因此位数必须匹配。因此,此处无法使用 office/ACE 的 x64 位版本。 - Albert D. Kallal
谢谢Gord!安装64位的Python 3.4完美无缺!现在找不到提供程序JET.OLEDB.4.0,但可以找到ACE.OLEDB.12.0。ODBC中的驱动程序也是如此。 - Parfait

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接