基于PostgreSQL查询结果动态构建带键级类型提示的字典
我正在使用Python、PostgreSQL及psycopg2搭建CRUD功能,当前聚焦于查询(Read)操作。默认游标查询返回元组,为提升可读性,我希望将结果重新封装为字典(存在XY问题:是否不该这么做?)。通过cursor.description可获取列名与类型,但需要能同时存储标签和类型的结构。pool_settings表字段类型为str、int、int、int,现有代码如下:
def read_pool_settings(site): connection = create_connection() cursor = connection.cursor() cursor.execute( f''' SELECT * FROM pool_settings WHERE site = '{site}'; ''') output = cursor.fetchone() column_info = [(desc[0], desc[1]) for desc in cursor.description] connection.close() dict_output = dict() for index, info in enumerate(column_info): dict_output[info[0]] = output[index] # something about type hinting with info[1] here return dict_output
我知道可用dict[str, Union[str, int]]声明类型,但希望每个键都有单独的类型提示(用于IDE hover提示,非编译调试)。我也了解过typing.TypedDict,但它需要手动声明类型,不符合我的需求。请问在Python中这是否无法实现?
先回应你的XY问题:转字典是合理需求,且有更简便的实现方式
psycopg2本身提供了直接返回字典结果的方案,不用手动封装——使用psycopg2.extras.DictCursor作为游标类型,fetchone()会直接返回类似字典的DictRow对象,既支持索引访问也支持列名访问,部分IDE还能关联数据库schema识别列名。同时必须修正你代码里的SQL注入风险,改用参数化查询:
from psycopg2.extras import DictCursor def read_pool_settings(site): connection = create_connection() # 指定DictCursor游标类型 cursor = connection.cursor(cursor_factory=DictCursor) # 参数化查询避免SQL注入 cursor.execute( ''' SELECT * FROM pool_settings WHERE site = %s; ''', (site,) ) output = cursor.fetchone() connection.close() # 可直接转为普通字典,或返回原生DictRow return dict(output) if output else None
关于动态生成带精确键类型提示的字典
回到核心问题:Python里无法动态生成让IDE识别的、每个键对应单独类型的字典结构。原因是IDE的类型提示依赖静态类型信息,而你要的是从数据库元数据动态生成的类型,属于运行时信息,静态分析工具(包括IDE)无法提前识别。
TypedDict是静态类型声明,必须提前定义键与对应类型;dict[str, Union[str, int]]只能给出宽泛的类型范围,做不到每个键单独提示。如果一定要追求IDE的精确提示,只能通过手动维护TypedDict,或者用代码生成工具(比如自己写脚本读取数据库元数据,自动生成对应TypedDict类)来实现。
总结:
- 追求便捷性:用
DictCursor直接返回字典结构,足够满足可读性需求 - 追求精确静态类型提示:只能手动或半自动生成
TypedDict,动态生成的字典无法让IDE识别每个键的单独类型
内容的提问来源于stack exchange,提问作者Joa

