python - 当 Access 使用 python 具有“Nz”表达式时,从 MS Access 导出到 Excel
问题描述
我有一个要导出到 excel 的访问表,但访问表(以及它调用的一些表)使用“Nz”表达式。我尝试用 IIf(IsNull( 甚至合并,但我似乎无法得到任何工作。我知道 pyodbc 访问驱动程序不支持他的 Nz 表达式,所以我试图找出解决方法。此外,我无权对 Access 数据库进行任何更改(这可能是最简单的解决方案。
另一个问题是连接中的某些列也有 NZ 表达式。对于脚本遇到的任何 Nz 表达式,可能会给出一个总值为 0 的东西?我不太使用 sql,所以这可能很容易,但我无法弄清楚如何。
我已经在没有 Nz 表达式的表上运行代码并且它可以工作,所以我知道驱动程序/cnxn 是正确的。
import pyodbc
import pandas as pd
ly_rep_temp_path = r"C:\examplePath\msAccessFile.accdb"
temp_path = r"C:\example\temoraryStorage"
driver = '{Microsoft Access Driver (*.mdb, *.accdb)}'
cnxn = pyodbc.connect(Driver=driver, DBQ=ly_rep_temp_path)
sql = """
SELECT rep.old, rep.new, Left(Nz([oldI].[mName],""),10) AS oldM, Left(Nz([newI].[mName],""),10) AS newM, oldI.primary AS oldS, newI.primary AS newS, oldI.primaryMR AS oldR, newI.primaryM AS newR,
FROM export_byI INNER JOIN ((rep INNER JOIN availableI AS oldI ON rep.olIs = oldI.isI) INNER JOIN availableI AS newI ON rep.nIsI = newI.isI) ON export_byI.IstI = rep.nwIsI
ORDER BY rep.nwIsI;
"""
crsr = cnxn.execute(sql)
for row in crsr.fetchall():
lpd_df = pd.read_sql(sql, cnxn)
print(lpd_df.columns)
lpd_df.to_excel(temp_path + '/zFinal.xlsx')
full_export_path = (temp_path + '/zFinal.xlsx')
# return full_export_path
crsr.close()
cnxn.close()
运行代码时出现以下错误:“pyodbc.ProgrammingError: ('42000', “[42000] [Microsoft][ODBC Microsoft Access Driver] Undefined function 'Nz' in expression. (-3102) (SQLExecDirectW)” )"
解决方案
因此,如果我们有一个名为 [Donor] 的表
DonorID DonorName Comments
------- --------- -------------
1 Gord cheapskate
2 Bill
3 Marsha Jan's nemesis
和一个名为 [query1] 的已保存查询,它使用Nz()
SELECT Donor.DonorID, Donor.DonorName, Nz([Comments],"(no comment)") AS txt
FROM Donor;
这会在 Microsoft Access 应用程序本身中产生以下内容
DonorID DonorName txt
------- --------- -------------
1 Gord cheapskate
2 Bill (no comment)
3 Marsha Jan's nemesis
如果我们尝试crsr.execute("SELECT * FROM query1")
在 pyodbc 中做,我们会得到
"pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access Driver] 表达式中未定义函数'Nz'。(-3102)
因为Nz()
不是 Access 数据库引擎 (ACE) 的内置功能;它是 VBA 表达式引擎的一部分。因此,为了从 Python 执行该查询,我们需要使用pywin32和 COM 自动化来运行 MSACCESS.EXE 的实例并以这种方式执行查询:
"""
requires: pip install pywin32
"""
import win32com.client
# ACE.DAO constants
dbOpenDynaset = 2
msa = win32com.client.Dispatch("Access.Application")
msa.OpenCurrentDatabase(r"C:\Users\Public\Database1.accdb")
db = msa.CurrentDb()
rst = db.OpenRecordset("SELECT * FROM query1", dbOpenDynaset)
while not rst.EOF:
print(rst.Fields("txt").Value)
rst.MoveNext()
"""console output:
cheapskate
(no comment)
Jan's nemesis
"""
msa.Quit()
编辑:如果要将查询导出到 Excel,可以直接从Access.Application
实例中执行此操作:
acExport = 1
acSpreadsheetTypeExcel12Xml = 10
msa.DoCmd.TransferSpreadsheet(
acExport, acSpreadsheetTypeExcel12Xml, "query1", r"C:\__tmp\test.xlsx"
)
msa.Quit()
推荐阅读
- jquery - jquery - 来自另一个函数的引用值
- javascript - 如何在 reactjs 中处理时间选择器选择
- java - Java MySQl - 过于频繁地打开和关闭连接?
- python - 如何在 keras CNN 中使用黑白图像?
- amazon-web-services - CodePipline Terra来自 || 操作“部署”的操作配置包含未知配置“部署组”
- angular - Angular 10:使用 HttpInterceptor 进行单元测试,它修改了没有得到 HttpResponse 的响应
- python - TypeError:无法将 str 连接到 HTTPSConnection 中的字节
- java - 该程序只是从用户那里获取输入,但不显示输出。在 main 函数中没有退出 while 循环
- javascript - 如何为 NodeJs 中的方法设置时间限制?
- java - Spring Boot Mongo Reactive 类未找到 - 找不到类 [org.springframework.data.mongodb.MongoDatabaseFactory]