Python中如何将DuckDB虚拟表接入其他数据库SQL语句做关联查询
问题根因
- 类型错误直接原因:你尝试将DataFrame对象
IDS直接和字符串拼接构造SQL语句,Python不支持DataFrame与字符串做加法运算,这就是UFuncTypeError报错的触发原因,并非你认为的「两边类型一致」。 - 逻辑错误核心原因:你通过pyodbc连接Access执行SQL时,Access的数据库引擎完全无法识别DuckDB中注册的虚拟表,哪怕解决了类型问题,原有逻辑也不可能跑通。
- 其他笔误:原代码中
cursor = conn.cursor()错用了DuckDB的连接对象conn,应该用Access的连接connt;存在无意义的孤立变量sfd;未导入os模块就调用os.system方法。
最优解决方案(完全满足跨源联表需求)
用DuckDB的ODBC扩展直接挂载Access数据库,你可以直接在DuckDB的SQL中同时操作DuckDB侧的DataFrame/虚拟表和Access侧的原生表,实现你要的跨源联表逻辑,和SAS PROC SQL的使用体验完全一致。
修改后可运行代码如下:
import pyodbc import pandas as pd import duckdb import os # 初始化DuckDB连接 conn = duckdb.connect() # 安装并加载ODBC扩展,用于挂载外部数据库 conn.execute("INSTALL odbc; LOAD odbc;") # 读取Excel生成DataFrame并注册为DuckDB虚拟表 starterset = pd.read_excel(r'e:\Data Analytics\Python_Projects\Applications\DB_Test.xlsx') conn.register("test_starter", starterset) # 挂载Access数据库到DuckDB,命名为access_db access_conn_str = r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=E:\Databases\Offline.accdb;' conn.execute(f"ATTACH '{access_conn_str}' AS access_db (TYPE ODBC);") StartDate = '2015-01-01' EndDate = '2021-12-01' # 直接在DuckDB中写跨源联表SQL,同时操作DuckDB侧虚拟表和Access侧原生表 query = """ SELECT t.ProjectID, t.Revenue, t.ClosedDate FROM access_db.Projects t INNER JOIN test_starter s ON t.ProjectID = s.ProjectID WHERE s.ProjectID > 1 AND t.ClosedDate BETWEEN ? AND ? AND t.Revenue > 0 ORDER BY t.ClosedDate """ # 执行参数化查询,避免SQL注入和日期格式兼容问题 df = conn.execute(query, [StartDate, EndDate]).fetchdf() # 输出结果 df.to_excel(r'TEMP.xlsx', index=False) os.system("start EXCEL.EXE TEMP.xlsx") # 关闭连接 conn.close()
替代方案(仅用于简单过滤场景)
如果你坚持用pyodbc直接查询Access,可以把过滤字段转成SQL识别的格式,比如把ProjectID列表转成IN条件:
# 从IDS中提取ProjectID列表转为SQL识别的字符串格式 id_list = ','.join(IDS['ProjectID'].astype(str)) query = f""" Select ProjectID, Revenue, ClosedDate from Projects WHERE ProjectID IN ({id_list}) AND ClosedDate between #{StartDate}# and #{EndDate}# AND Revenue > 0 order by ClosedDate """
注意:该方案仅适合单维度简单过滤场景,多维度关联需求还是优先使用第一种DuckDB挂载方案。
内容的提问来源于stack exchange,提问作者J. Alexander
相关产品推荐
相关产品推荐

