合并Oracle与SSMS来源的DataFrame时触发KeyError问题求助
错误提示KeyError: "None of [Index(['BI.BookingItemID'], dtype='object')] are in the [columns]"的核心原因是:你尝试从SSMSData中选取BI.BookingItemID列,但这个列根本不存在于该DataFrame中。结合你的代码,问题出在这几个地方:
1. 列名的表前缀误区
你在SQL查询里写了BI.BookingItemID、CTLA.ATTRIBUTE12这类带表前缀的字段,但Pandas读取SQL查询结果时,默认不会保留表前缀(除非你在SQL语句里用AS显式指定别名)。比如你的SSMS查询如果是SELECT BI.BookingItemID FROM ...,返回的列名只会是BookingItemID,而非BI.BookingItemID。
2. Merge参数逻辑矛盾
你合并时先取了SSMSData[['BI.BookingItemID']](只保留这一列),但又指定right_on = 'CTLA.ATTRIBUTE12'——这完全矛盾,子集里根本没有CTLA.ATTRIBUTE12这个列,说明你搞混了两个DataFrame的连接字段。
修复步骤
第一步:确认实际列名
在合并前先打印两个DataFrame的列名,明确真实存在的字段:
print("Odata列名:", Odata.columns.tolist()) print("SSMSData列名:", SSMSData.columns.tolist())
比如实际结果可能是:Odata里的连接字段是BookingItemID,SSMSData里的是ATTRIBUTE12。
第二步:修正合并代码
根据实际列名调整merge参数,举个正确的例子:
# 若不需要过滤SSMSData的列,直接用完整DataFrame合并 merge = pd.merge(Odata, SSMSData, left_on='BookingItemID', # 替换为Odata实际的连接列名 right_on='ATTRIBUTE12', # 替换为SSMSData实际的连接列名 how='left')
如果确实只需要SSMSData里的特定列,要确保包含连接字段:
merge = pd.merge(Odata, SSMSData[['ATTRIBUTE12', '你需要的其他列']], left_on='BookingItemID', right_on='ATTRIBUTE12', how='left')
第三步:(可选)用SQL别名固定列名
如果希望SQL返回的列名带标识,可以在查询里用AS指定别名,比如SSMS的查询语句:
SELECT CTLA.ATTRIBUTE12 AS CTLA_ATTRIBUTE12, BI.BookingItemID AS BI_BookingItemID FROM ...
这样Pandas读取的列名就是你指定的别名,后续合并时能准确引用。
内容的提问来源于stack exchange,提问作者LRoffers

