kn9ka
kn9ka

Reputation: 33

How to create permanent MS Access Query by Python 3.5.1?

I have about 40 MS Access Databases and have some troubles if need to create or transfer one of MS Access Query (like object) from one db to other dbs. So I tried to solve this problem with pyodbc but.. as I saw pyodbc doesn't support to create new, permanent MS Access Query (object). I can connect to db, create or delete tables/rows but can't to create and save new query.

import pyodbc

odbc_driver = r"{Microsoft Access Driver (*.mdb, *.accdb)}"

db_test1 = r'''..\Test #1.accdb'''
db_test2 = r'''..\Test #2.accdb'''
db_test3 = r'''..\Test #3.accdb'''
db_test4 = r'''..\Test #4.accdb'''

db_test_objects = [db_test1, db_test2, db_test3, db_test4]

odbc_conn_str = "Driver=%s;DBQ=%s;" % (odbc_driver, db_file)
print (odbc_conn_str)

conn = pyodbc.connect(odbc_conn_str)
odbc_cursor = conn.cursor()

NewQuery = "CREATE TABLE TestTable(symbol varchar(15), leverage double)"

odbc_cursor.execute(NewQuery)
conn.commit()
conn.close()

SO, How to create and save MS Access Query like objects from python? I tried to search info in Google, but the answers were related with Run SQL code.

On VBA this code looks like:

Public Sub CreateQueryDefX()

   Dim base(1 To 4) As String
   base(1) = "..\Test #1.accdb"
   base(2) = "..\Test #2.accdb"
   base(3) = "..\Test #3.accdb"
   base(4) = "..\Test #4.accdb"

   For i = LBound(base) To UBound(base)
    CurrentBase = base(i)
    Set dbo = OpenDatabase(CurrentBase)
        With dbo
        Set QueryNew = .CreateQueryDef("TestQuery", _
         "SELECT * FROM TestTable")
         RefreshDatabaseWindow
        .Close
        End With
   Next i

RefreshDatabaseWindow

End Sub

Sorry for my English, it's not my native :)

By the way, I know how to solve this by VBA, but I'm interested in solve this by python.

Thank you.

Upvotes: 3

Views: 1128

Answers (2)

Gord Thompson
Gord Thompson

Reputation: 123829

You can use a CREATE VIEW statement to create a saved Select Query in Access. The pyodbc equivalent to your VBA example would be

crsr = conn.cursor()
sql = """\
CREATE VIEW TestQuery AS
SELECT * FROM TestTable
"""
crsr.execute(sql)

To delete that saved query you could simply execute a DROP VIEW statement.

For more information on DDL in Access see

Data Definition Language

Upvotes: 5

Parfait
Parfait

Reputation: 107737

Consider the Python equivalent of the VBA running exactly what VBA uses: a COM interface to the Access Object library. With Python's win32com third-party module, you can call the CreateQueryDef method. Do note: this COM interfacing can be applied in other languages such as PHP and R!

Below uses a try/except/finally block to ensure the Access application process closes regardless of error or success of code (similar to VBA's On Error handling):

import win32com.client

# OPEN ACCESS APP AND DATABASE
dbases = ["..\Test #1.accdb", "..\Test #2.accdb", "..\Test #3.accdb", "..\Test #4.accdb"]

try:
    oApp = win32com.client.Dispatch("Access.Application")

    # CREATE QUERYDEF
    for db in dbases:
        oApp.OpenCurrentDatabase(db)
        currentdb = oApp.CurrentDb()
        currentdb.CreateQueryDef("TestQuery", "SELECT * FROM TestTable")
        currentdb = None
        oApp.DoCmd.CloseDatabase

except Exception as e:
    print(e)

finally:
    currentdb = None
    oApp.Quit
    oApp = None

Also, if you need to run DML statements via pyodbc and not a COM interface, consider distributed queries as Access can query other databases directly in SQL. Below should work in Python (be sure to escape the backslash):

SELECT t.* FROM [C:\Path\To\Other\Database.accdb].TestTable t

Upvotes: 1

Related Questions