5

I want to create an Access database (*.accdb) from within a Python script. Using win32com and Dispatch I can call the application. However, I cant find anything on how to create a new database.

access = win32com.client.Dispatch('Access.Application')

At that point I have no need to put data into the database and I would do this using pyodbc - I simply need to create an empty database.

Does somebody has an example on how to do this?

Cheers Thomas

Thomas Becker
  • 471
  • 3
  • 8
  • 16

3 Answers3

4

You have an Access application object. Use its DBEngine.CreateDatabase method to create your db file.

This sample worked from Python 2.7 to create an MDB format database file. To create an ACCDB, use 128 (dbVersion120) for dbVersion.

import win32com.client
oAccess = win32com.client.Dispatch('Access.Application')
DbFile = r'C:\Users\hans\Documents\NewDb.mdb'
dbLangGeneral = ';LANGID=0x0409;CP=1252;COUNTRY=0'
# dbVersion40 64
dbVersion = 64
oAccess.DBEngine.CreateDatabase(DbFile, dbLangGeneral, dbVersion)
oAccess.Quit()
del oAccess
HansUp
  • 95,961
  • 11
  • 77
  • 135
  • Excellent, that worked like a charm! Just one more question: Where do I gett all the information from that you set for dbLangGeneral? Cheers Thomas – Thomas Becker Mar 27 '13 at 15:08
  • From within an Access session, I used `Debug.Print dbLangGeneral` and copied the string it returned. See the CreateDatabase help topic for details about other options. – HansUp Mar 27 '13 at 15:12
1

To create a new, empty .accdb file, the following Python code should do the trick:

import win32com.client
f = 'C:\\Users\\Gord\\Desktop\\pyTest.accdb'
c = win32com.client.Dispatch('ADOX.Catalog')
c.Create('Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + f + ';')
c = None
print '"' + f + '" created.'

[Edit 1]

A comment to a blog posting here suggests that if the .Create call generates a "Class not registered" error you may need to use regsvr32.exe to re-register msadox.dll. Be aware of "bitness" when you attempt this: There are 32-bit and 64-bit versions of both of those files:

64-bit
C:\Windows\System32\regsvr32.exe
C:\Program Files\Common Files\System\ado\msadox.dll

32-bit
C:\Windows\SysWOW64\regsvr32.exe
C:\Program Files (x86)\Common Files\System\ado\msadox.dll

Also, be aware that you could be running 32-bit Python on a 64-bit machine.

[Edit 2]

I've done a few tests and have reached the conclusion that this approach did not work in this particular case because the Python script was running as 64-bit, but the 64-bit Access Database Engine was not installed. (32-bit Office only installs the 32-bit version of ACE.)

The error message was perhaps a bit misleading. It wasn't the ADOX component that was missing (not registered), it was the 64-bit version of the ACE engine itself that couldn't be found.

Furthermore, on a 64-bit machine with 32-bit Access installed, the 64-bit version of ACE will never be available because it cannot be installed

no 64-bit ACE with 32-bit Office

This could very well have implications when you try to manipulate data within the .accdb file from a 64-bit Python script. I didn't have Python available on my "32-bit Office on 64-bit Windows" test machine, but when I tried the following VBScript...

Option Explicit
Dim con, rst
Set con = CreateObject("ADODB.Connection")
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data source=C:\Users\Gord\Desktop\adoTest.accdb;"
Set rst = CreateObject("ADODB.Recordset")
rst.Open "SELECT Field1 FROM Table1", con
Wscript.Echo rst(0).Value
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing

...the results were as follows:

C:\__tmp>C:\Windows\System32\cscript.exe /nologo dataAccessTest.vbs
C:\__tmp\dataAccessTest.vbs(4, 1) ADODB.Connection: Provider cannot be found. 
It may not be properly installed.

C:\__tmp>C:\Windows\SysWOW64\cscript.exe /nologo dataAccessTest.vbs
This is Table1 data in Access.

The script failed when run as 64-bit, but it worked when run as 32-bit.

Recommendation: If your machine has 32-bit Access installed you'll probably be better off running your Python scripts as 32-bit too.

Gord Thompson
  • 116,920
  • 32
  • 215
  • 418
  • Hi Gord, thanks for the fast reply! Unfortunately it doesn't do the trick yet. I'm getting the following error: Traceback (most recent call last): File "C:\THOB\workspace\Toolbox\src\whales.py", line 102, in access.Create('Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + fpDB + ';') File "", line 2, in Create File "C:\Python27\ArcGISx6410.1\lib\site-packages\win32com\client\dynamic.py", line 282, in _ApplyTypes_ result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args) – Thomas Becker Mar 27 '13 at 12:37
  • pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, u'Class not registered', None, 0, -2147221164), None) – Thomas Becker Mar 27 '13 at 12:40
  • Thanks a lot! I'm absolutely sure that I'm running the 64-bit version. I think I will try with the 32-bit version of msadox.dll since MS Office is 32-bit. Hope that will solve the problem. – Thomas Becker Mar 27 '13 at 13:32
  • Thanks a lot! I'm absolutely sure that I'm running the 64-bit version. I tried both possibilities and unfortunately it doesn't change the error message. – Thomas Becker Mar 27 '13 at 14:13
  • @ThomasBecker Sorry, but I don't have any more ideas except to try the method suggested by HansUp in the other answer. FWIW, I did test the ADOX solution before I posted my answer and it worked for me (32-bit Python on 64-bit Vista with 64-bit Office installed). – Gord Thompson Mar 27 '13 at 15:01
  • Thanks again, and the way HansUp suggested works very well. I'm using a a 64-bit Python 27 on 64-bit Win7 but the office version installed is 32-bit... – Thomas Becker Mar 27 '13 at 16:13
  • @ThomasBecker Answer updated. You may be interested in the last bit re: data access. – Gord Thompson Mar 27 '13 at 17:39
  • 1
    @HansUp Heh, yeah. And change just one character in "bit-ness" and you've got "bit-mess", which seems somewhat appropriate, too. :) – Gord Thompson Mar 27 '13 at 18:31
0
import win32com.client
ConFileName = r'c:\mydb\myaccess.mdb'
try:
    Catalog = win32com.client.Dispatch('ADOX.Catalog')
    Catalog.Create('Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + ConFileName + ';')
    Catalog = None
except:
    Exception as e:
        print("Database generation failed, Error="+str(e))
print("NewAccessDB.mdb created successfully")

Then you can connect to access database :

ConFileName=(r'c:\mydb\myaccess.mdb')
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' + ConFileName + ';')
cursor = conn.cursor()

To insert in to the access table :

ConFileName=(r'c:\mydb\myaccess.mdb')
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' +ConFileName+ ';')
cursor = conn.cursor()
for ta in TableArray:
    Sql_insert_query = "INSERT INTO Table1(ID, Value1,Value2,Value3,Value4,Value5,Value6) " \
                         "VALUES ('{a}','{b}','{c}','{d}','{e}','{f}','{g}')".format(a=str(ta[0]),b=str(ta[1]),c=str(ta[2]),d=str(ta[3]),e=str(ta[4]),f=str(ta[5]),g=str(ta[6]))
    cursor.execute(Sql_insert_query)
    conn.commit()
cursor.close()

Please follow this link for more information :

https://elvand.com/python-and-ms-access/

Masoud.Ebrahimi
  • 309
  • 3
  • 4