Oppposite Workings of OLEDB/ODBC between Python and MS Access VBA

六眼飞鱼酱① 提交于 2019-12-01 08:29:13

问题


Fellow more advanced programmers:

Please forgive me if this seems like the tired Python 32-bit/64-bit ODBC/OLEDB Windows issue but I tried searching the forums and can't quite find the reason to my issue.

Basically, I tried to connect a very simple Python script first via ODBC using the pypyodbc module, and then second via OLEDB using the adodbapi module, both attempts to an MS Access 2010 .accdb database. However, for OLEDB I consistently get the 'Provider not found. It may not be properly installed' error. And for ODBC I consistently receive the 'Data source name not found and no default driver specified'.

Digging deeper, something remarkable happened though. In Python, JET.OLEDB.4.0 works for .mdb files but not ACE.OLEDB.12.0 for .accdb files. Yet, the exact reverse happens when I ran an Access VBA ADODB connection!

My environment includes:

  • Python3.4 -32-bit
  • pywin32-219 (installed with post-install)
  • Microsoft Office 2010 64-bit
  • Windows 7

Yes, I downloaded and successfully installed the AccessDatabaseEngine_x64.exe. Yes, I pointed ODBC data sources to %Win%/SysWOW64. Yes, I see the Access driver and datasources for mdb and accdb in odbcad32.exe in aforementioned folder. Yes, I see the registry keys in regedit for Access (*mdb) and Access (*mdb, *accdb) data sources and Access driver. And yes, I both restarted and shut off/on my machine.

OLEDB
The following is my connection string that returns the 'Provider not found error...':

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

Remarkably though, the following connection string works perfectly but of course only with .mdb files:

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


ODBC
The following is my connection string that returns the 'Data source name not found...':

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

Like above, the following works ideally but only for .mdb files:

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


Access VBA
Interestingly, the EXACT reverse happens in an Access VBA module (of course with the ActiveX Data Object library reference) using the same connections strings both Driver and Provider.

Code works perfectly for both .mdb and .accdb files:

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)

Code returns error - 'Provider not found' or 'Specified driver could not be loaded':

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
Finally, still in Access VBA, only the Provider: Microsoft.ACE.OLEDB.12.0 works which I thought corresponded to MS Access 2007. However, the Provider: Microsoft.ACE.OLEDB.14.0 does not work for my installed MS Access 2010. Any reasons for this?

Conclusion
I understand ActiveX library is a different technology than Python's module library and Microsoft does not allow simultaneous use of components in x32-bit and x64-bit but why can't I get my intended result. I thought about the AccessDatabaseEngine_x64.exe /passive but I hear weird Office results going that route. Do I need to install Python3.4 for 64-bit? Please help or suggest! Thanks.


回答1:


Short answer:

Yes, to minimize headaches you should be running a 64-bit version of Python if you have 64-bit Office installed and you want to manipulate Access databases from Python.

Longer answer:

The older "Jet" engine/drivers and the newer Access Database Engine (a.k.a. "ACE") engine/drivers are completely separate entities.

The older "Jet" drivers...

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

... are installed as an integral part of the Windows OS but they only available to 32-bit applications.

You have 64-bit Office installed, so you have the 64-bit version of the newer "ACE" drivers ...

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

... and they are only available to 64-bit applications.

Your current 32-bit Python environment can use the Jet drivers but not the ACE drivers

You have the 64-bit version of Access, therefore your VBA code is running in the 64-bit universe and it can use the ACE drivers but not the Jet drivers.



来源:https://stackoverflow.com/questions/25951912/oppposite-workings-of-oledb-odbc-between-python-and-ms-access-vba

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!