Python:嵌套字典键缺失时如何高效返回NULL并避免脚本崩溃?
处理嵌套字典缺失键的简便方案(psycopg2入库场景)
问题背景
从API获取嵌套字典格式数据,使用psycopg2写入数据库时,偶尔会遇到字典缺少所需键的情况导致脚本崩溃。手动为每个字段编写try/except块处理缺失键的方式过于繁琐,需要更简洁的实现方案。
原代码示例
正常数据场景
mydict = {'name': {'firstname': 'Peter', 'surname': 'Pan'}, 'contact': {'hometown': 'Neverland', 'phone': '123-456'}} sql = f"INSERT INTO mytable(firstname, surname, phone)\nVALUES\n(" sql += f"'{mydict['name']['firstname']}'," sql += f"'{mydict['name']['surname']}'," sql += f"'{mydict['contact']['phone']}');"
手动处理缺失键的繁琐写法
mydict = {'name': {'firstname': 'Peter', 'surname': 'Pan'}, 'contact': {'hometown': 'Neverland'}} sql = f"INSERT INTO mytable(firstname, surname, phone)\nVALUES\n(" try: sql += f"'{mydict['name']['firstname']}'," except KeyError: sql += 'NULL' try: sql += f"'{mydict['name']['surname']}'," except KeyError: sql += 'NULL' try: sql += f"'{mydict['contact']['phone']}');" except KeyError: sql += f"NULL);"
优化方案
1. 通用嵌套键取值函数 + 参数化查询
先编写一个辅助函数处理嵌套字典的键取值,遇到缺失键直接返回None(psycopg2会自动将None转换为SQL的NULL),同时使用参数化查询避免SQL注入风险:
def get_nested_value(data, key_chain): """从嵌套字典按键链取值,缺失则返回None""" current = data for key in key_chain: try: current = current[key] except (KeyError, TypeError): return None return current # 字段与嵌套键链的映射 field_keys = [ ['name', 'firstname'], ['name', 'surname'], ['contact', 'phone'] ] # 提取所有字段值 values = [get_nested_value(mydict, keys) for keys in field_keys] # 参数化SQL语句 sql = "INSERT INTO mytable(firstname, surname, phone) VALUES (%s, %s, %s);" # 执行入库(假设已建立数据库连接conn) import psycopg2 with conn.cursor() as cur: cur.execute(sql, values) conn.commit()
2. 逐层使用dict.get()(适合简单嵌套)
如果嵌套层级较少,直接用dict.get()逐层取值,每层设置默认空字典继续下一层,最终缺失时返回None:
firstname = mydict.get('name', {}).get('firstname') surname = mydict.get('name', {}).get('surname') phone = mydict.get('contact', {}).get('phone') # 参数化查询入库 sql = "INSERT INTO mytable(firstname, surname, phone) VALUES (%s, %s, %s);" with conn.cursor() as cur: cur.execute(sql, (firstname, surname, phone)) conn.commit()
重要提示
绝对不要手动拼接包含变量的SQL字符串,这种做法存在严重的SQL注入漏洞。psycopg2的参数化查询不仅能自动处理Python类型到SQL类型的转换(如None转NULL),还能彻底避免注入风险,同时代码更简洁易维护。
内容的提问来源于stack exchange,提问作者Suti
相关产品推荐
相关产品推荐

