如何修复Python 3中'tuple indices must be integers or slices, not str'错误
问题描述
错误信息
File "/opt/api/./WrapperMultiple.py, line 428, in ids_to_epis
epis=[int(epi) for epi in list(epis['epi'])]
TypeError: tuple indices must be integers or slices, not str
补充说明
epis预期应为DataFrame类型,但实际返回了tuple,导致无法通过字符串索引取值。
待修复代码片段
def ids_to_epis(ids, type): select=[] for id in ids: select = " union all ".join(select) query = """ with ids as ( {select} ) select max (random) as epi from randomTable i join ids on ids.id = i.new_id and new_idtype={type} group by i.new_id """.format(select=select,type=type) bi_conn=SQLConnector(db='bi') epis=bi_conn.query_by_str(query) epis=[int(epi) for epi in list(epis['epi'])] return epis
问题分析与修复
核心原因
- SQL查询构造无效:
select列表初始化后,循环内未添加任何查询片段就执行join,导致最终生成的SQL中ids子查询为空,数据库返回异常结果(非预期的DataFrame)。 - 返回值类型不匹配:当SQL查询出错或无结果时,
bi_conn.query_by_str()可能返回tuple而非DataFrame,后续用epis['epi']索引自然触发类型错误。
修复方案
1. 修正SQL查询构造逻辑
在循环中为select列表添加每个ID对应的查询语句,确保ids子查询有有效内容。
2. 增加类型校验与兼容处理
针对query_by_str()可能返回的不同类型(tuple、空结果等)做兼容处理,避免索引报错。
3. 改用参数化查询
避免直接字符串格式化传递参数,防止SQL注入并提升查询稳定性。
修改后的代码
def ids_to_epis(ids, id_type): # 构造每个ID对应的查询片段 select_clauses = [f"SELECT {id} AS id" for id in ids] if not select_clauses: return [] # 空ID列表直接返回空结果 select_union = " UNION ALL ".join(select_clauses) query = """ WITH ids AS ( {select_union} ) SELECT MAX(random) AS epi FROM randomTable i JOIN ids ON ids.id = i.new_id AND new_idtype = %s GROUP BY i.new_id """.format(select_union=select_union) bi_conn = SQLConnector(db='bi') # 使用参数化查询传递id_type epis = bi_conn.query_by_str(query, params=(id_type,)) # 兼容不同返回类型 if hasattr(epis, 'get'): # 处理DataFrame或字典类型 epi_values = epis.get('epi', []) elif isinstance(epis, (list, tuple)): # 处理返回为元组列表的情况(如每行数据是(epi_value,)) epi_values = [row[0] for row in epis if row] else: return [] # 转换为整数并过滤空值 return [int(epi) for epi in epi_values if epi is not None]
额外优化点
- 将变量名
type改为id_type,避免与Python内置关键字冲突。 - 增加空ID列表的边界处理,避免生成无效SQL。
- 增强类型判断逻辑,兼容数据库连接返回的多种格式。
内容的提问来源于stack exchange,提问作者Software Developer In Training
相关产品推荐
相关产品推荐

