2016-09-23 40 views
3

我有大约40个MS Access数据库,并且如果需要从一个数据库创建或转移一个MS Access查询(如对象)到其他数据库时遇到一些麻烦。 所以我试图用pyodbc解决这个问题,但是..正如我所见,pyodbc不支持创建新的,永久的MS Access查询(对象)。 我可以连接到数据库,创建或删除表/行,但不能创建并保存新的查询。如何通过Python 3.5.1创建永久MS Access查询?

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() 

那么,如何创建和保存MS Access查询像Python对象? 我试图在Google中搜索信息,但答案与有关,运行SQL代码

在VBA这段代码看起来像:

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 

对不起,我的英语,这不是我的母语:)

顺便说一句,我知道如何通过VBA来解决这个问题,但我有兴趣通过python解决这个问题。

谢谢。

回答

5

您可以使用CREATE VIEW语句在Access中创建已保存的选择查询。相当于您的VBA例如pyodbc是

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

要删除保存的查询,你可以简单地执行DROP VIEW声明。

对于访问的DDL更多信息,请

Data Definition Language

+0

Gord,谢谢。我会再问一个问题吗?如何删除创建的视图?我将非常感谢像CREATE VIEW之类的pyodbc语句链接。我无法在文档中找到您的信息。 – kn9ka

+0

@ kn9ka - 我已经更新了我的答案。 –

1

考虑的Python相当于VBA的运行正是VBA使用:一个COM接口来访问对象库。使用Python的win32com第三方模块,您可以调用CreateQueryDef方法。请注意:此COM接口可以用于其他语言,如PHP和R!

下面使用try/except/finally块,以确保访问应用程序关闭,无论错误或代码成功(类似于VBA的On Error处理):

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 

另外,如果你需要运行DML语句通过pyodbc而不是COM接口,考虑分布式查询,因为Access可以直接在SQL中查询其他数据库。下面应该在Python中工作(一定要避开反斜杠):

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

Parfait,谢谢,这是可行的,但COM对象有一个大问题,那就是安全选项。在我的情况下,并不是每个人都有权改变它们。 – kn9ka