我正在尝试从访问数据库中提取表列表。该脚本遍历并显示大约三分之一的表并出现以下错误:
Traceback(最近调用最后一次):文件“C:/GageInfo/sourcecode for GageTrakNotify/__test script.py”,第 31 行,在 for fld in cursor2.columns(rows.table_name): UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position 132-133: illegal 编码
任何提示将不胜感激。
import pyodbc
cursor1 = conn.cursor()
cursor2 = conn.cursor()
tblCount = 0
for rows in cursor1.tables():
if rows.table_type == "TABLE":
tblCount += 1
print(rows.table_name)
for fld in cursor2.columns(rows.table_name):
print(fld.table_name, fld.column_name)
conn.close()
如果表元数据包含列的“描述”,这几乎肯定是由使用 Access ODBC 驱动程序时
cursor.columns()
的已知问题引起的。以下 GitHub 问题包括对问题和可能的解决方法的讨论:
https://github.com/mkleehammer/pyodbc/issues/328
TL;DR:Access ODBC 驱动程序在这些情况下返回尾随垃圾字节,并且字节的某些组合将不是有效的 UTF-16LE 编码字符。 pyodbc 输出转换器函数可用于拦截字节字符串并在不抛出异常的情况下对其进行解码。具体的解决方法在这里描述:
https://github.com/mkleehammer/pyodbc/issues/328#issuecomment-419655266
感谢您的提示和反馈。我通过捕获列表中的信息然后打印出结果并使用 try 语句处理错误并应用正确的 unicode 来解决它。
您的建议为我指明了正确的方向。
这是我的第一个回答,如果它很笼统,我深表歉意。
设置解码:
conn.setdecoding(pyodbc.SQL_WCHAR, encoding='latin-1')
放在conn.cursor()之前:
conn = pyodbc.connect(conn_str)
此外,您可能会错过它:
conn_str = (
r"DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};"
r"DBQ=path\to\your\access\database.accdb;"
r"unicode_results=True;"
)
听起来您在某处的表名中嵌入了 Unicode(非 ASCII)。弄清楚它在哪个表上停止将确认是否是这种情况,但最终您希望 Python 脚本只处理 Unicode,这可以使用字符串
decode
方法来完成:
for fld in cursor2.columns(rows.table_name.decode('utf-16-le')):
这应该在任何可能出现 Unicode 字符的地方进行(例如,列名)。