MariaDB Connector/Python第252次迭代返回空cursor.fetchall()问题求助
问题排查求助:MariaDB Python Connector第252次迭代必返回空结果
限制条件
- Linux发行版限制无法将Connector/C升级至3.1.20以上,因此Python模块版本固定为1.0.11
版本信息
从/usr/bin/mariadb_config获取的版本:
Copyright 2011-2020 MariaDB Corporation AB Get compiler flags for using the MariaDB Connector/C. Usage: mariadb_config [OPTIONS] Compiler: GNU 10.2.1 --version [10.5.19] --cc_version [3.1.20]
输出日志
***** ***** ***** ***** ***** ***** ***** ***** ***** ***** Executing SQL Query: "SELECT cardid,mfguid,setTCGUid ,CONCAT_WS(' ',REGEXP_REPLACE(REGEXP_REPLACE(ed.editionName,'^(.*)(| Edition)$','\\1 Edition'),'(Alpha Print Edition|1st Edition Edition)','1st Edition'),REPLACE(f.finishName,'Regular','Normal')) AS printing from g1st_fabdb.cards left join g1st_fabdb.setNames sn ON cards.setNameId=sn.setNameId LEFT JOIN g1st_fabdb.finishes f ON cards.finishId = f.finishId LEFT JOIN g1st_fabdb.editions ed ON cards.editionId = ed.editionId WHERE ( mfguid LIKE %s )AND setTCGUid = %s ;" Values:"%RVD026%" "RVD Card Data: [(148982, 'RVD026', 'RVD', 'Rhinar Edition Normal')] cardid mfguid setTCGUid printing 0 148982 RVD026 RVD Rhinar Edition Normal DBCursor Status: <mariadb.connection connected to 'localhost' at 0xffff8929bb40> True DBCardID: cardid mfguid setTCGUid printing 0 148982 RVD026 RVD Rhinar Edition Normal Length: 1 CardId 0: cardid mfguid setTCGUid printing 0 148982 RVD026 RVD Rhinar Edition Normal Card Last Updated SQL Query: SELECT card_lastupdate from g1st_fabdb.marketdata WHERE cardid=148982 ORDER BY card_lastupdate DESC LIMIT 1 Card Last Updated in DB: None In API: 2023-05-26 21:53:45 ***** In Set: RVD Card In set: 026 SETID: RVD026 ***** ***** Current CardCount total: 251 ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** Executing SQL Query: "SELECT cardid,mfguid,setTCGUid ,CONCAT_WS(' ',REGEXP_REPLACE(REGEXP_REPLACE(ed.editionName,'^(.*)(| Edition)$','\\1 Edition'),'(Alpha Print Edition|1st Edition Edition)','1st Edition'),REPLACE(f.finishName,'Regular','Normal')) AS printing from g1st_fabdb.cards left join g1st_fabdb.setNames sn ON cards.setNameId=sn.setNameId LEFT JOIN g1st_fabdb.finishes f ON cards.finishId = f.finishId LEFT JOIN g1st_fabdb.editions ed ON cards.editionId = ed.editionId WHERE ( mfguid LIKE %s )AND setTCGUid = %s ;" Values:"%DRO001%" "DRO Card Data: [] False DBCursor Status: <mariadb.connection connected to 'localhost' at 0xffff8929bb40> True DBCardID: False Traceback (most recent call last): File "/home/biqu/scripts/api-dbupdate.py", line 367, in <module> if Debug : print("Length:",len(dfCardId)) TypeError: object of type 'bool' has no len()
Python函数
def get_dfCardId(SetID,sName): #replace with cardID identification function .,+6 if not mydberror : my_cardid_query="SELECT cardid,mfguid,setTCGUid ,CONCAT_WS(' ',REGEXP_REPLACE(REGEXP_REPLACE(ed.editionName,'^(.*)(| Edition)$','\\\\1 Edition'),'(Alpha Print Edition|1st Edition Edition)','1st Edition'),REPLACE(f.finishName,'Regular','Normal')) AS printing from g1st_fabdb.cards left join g1st_fabdb.setNames sn ON cards.setNameId=sn.setNameId LEFT JOIN g1st_fabdb.finishes f ON cards.finishId = f.finishId LEFT JOIN g1st_fabdb.editions ed ON cards.editionId = ed.editionId WHERE ( mfguid LIKE %s )AND setTCGUid = %s ;" mydbSetId="%{}%" if Debug: print("Executing SQL Query: \""+my_cardid_query+"\"\n\tValues:\""+mydbSetId.format(SetID)+"\"\n\t\t\""+sName) myconn_ro=mariadb.connect(**mydbparams) mydbcursor=myconn_ro.cursor() mydbcursor.execute(my_cardid_query,(mydbSetId.format(SetID),sName)) dbCardId = mydbcursor.fetchall() if Debug and myconn_ro.warnings > 0: print("Warnings: ",myconn_ro.warnings,"\n\t",myconn_ro.show_warnings) mydbcursor.close() myconn_ro.reset() if Debug: print("\t\tCard Data: ",dbCardId) if len(dbCardId)>0: dfCardId = pd.DataFrame(dbCardId,index=None,columns=('cardid','mfguid','setTCGUid','printing')) else: dfCardId = False # pd.DataFrame({'cardid':[''],'mfguid':[''],'setTCGUid':[''],'printing':['']}) print(dfCardId) if Debug: print("DBCursor Status: ",mydbcursor.connection," ",mydbcursor.closed) myconn_ro.close() return dfCardId
问题概述
Python函数执行SELECT语句时,无论使用何种WHERE子句,第252次迭代必然返回空的cursor.fetchall()结果,无警告、无错误、无异常,最终因返回False导致调用len(dfCardId)时触发TypeError。
已尝试的解决方案:
- 最初复用初始化一次的连接
- 使用ConnectionPool(但
connection.close()无法释放连接回池) - 按顺序执行cursor和connection关闭方法
- 每次迭代新建连接(但连接内存地址未变化)
以上尝试均无法解决问题,需要排查建议。
排查建议
检查数据库配置阈值:
- 查看MariaDB的
max_connections、wait_timeout、max_statement_time等参数,确认252是否触及某个连接或语句执行的上限。可以通过执行SHOW VARIABLES LIKE '%connection%';和SHOW VARIABLES LIKE '%timeout%';查看当前配置。
- 查看MariaDB的
捕获底层数据库错误:
- 在
execute和fetchall环节添加异常捕获,排查是否存在未抛出的底层错误:try: mydbcursor.execute(my_cardid_query,(mydbSetId.format(SetID),sName)) dbCardId = mydbcursor.fetchall() except mariadb.Error as e: print(f"DB Error: {e}") print(f"Error code: {e.args[0]}, SQL state: {e.args[1]}")
- 在
手动验证第252次请求的SQL:
- 提取第252次迭代的
SetID和sName,拼接成完整SQL语句在MariaDB客户端直接执行,确认是否真的无数据返回。如果客户端能查到数据,说明问题出在Connector/Python层面。
- 提取第252次迭代的
排查资源泄漏:
- 在
myconn_ro.close()后添加del myconn_ro、del mydbcursor强制释放对象,避免潜在的资源泄漏。 - 监控迭代过程中的系统资源(内存、文件句柄),查看第252次时是否达到系统限制(比如文件句柄耗尽)。
- 在
调整SQL参数传递方式:
- 将SQL中的
mfguid LIKE %s改为mfguid LIKE CONCAT('%', %s, '%'),直接传入不带通配符的SetID,绕过Connector对通配符字符串的特殊处理,排查是否是参数解析问题。
- 将SQL中的
尝试调整Connector版本:
- 虽然无法升级Connector/C,但可以尝试降级Python Connector到1.0.x的更早版本,看是否能规避该特定版本的bug。
内容的提问来源于stack exchange,提问作者Joe Greene
相关产品推荐
相关产品推荐

