如何定义与Snowflake cursor.description结果结构一致的列表?
问题描述
执行以下代码:
cursor.execute("select * from table") desc = cursor.description
执行print(desc)后输出:
[ResultSetMetadata(name='id', type='', precision=20 ...),ResultSetMetadata(name='name', type='', precision=20...)]
执行print(type(desc))后输出:
class 'list'
想要定义一个与desc结构完全一致的列表,直接编写以下代码时抛出错误 'name 'ResultSetMetadata' is not defined':
desc = [ResultSetMetadata(name='id', type='', prescision=20 ...),ResultSetMetadata(name='name', type='', prescision=20...)]
需求是编写单元测试代码,需要mock cursor.description的结果:
mock_cursor.description = desc
解决方案
有几种可行的方式构造符合要求的desc列表:
1. 直接复用原ResultSetMetadata类
从真实cursor的description结果中获取类的引用,无需提前知晓类的导入路径:
# 先获取真实环境下的desc(比如临时执行一次查询) real_desc = cursor.description # 提取元素对应的类 ResultSetMetadata = type(real_desc[0]) # 构造mock用的列表 mock_desc = [ ResultSetMetadata(name='id', type='', precision=20), ResultSetMetadata(name='name', type='', precision=20) ] # 赋值给mock cursor mock_cursor.description = mock_desc
2. 用namedtuple模拟结构
如果不想依赖真实数据库连接,可使用collections.namedtuple创建结构匹配的类,单元测试只需属性名匹配即可:
from collections import namedtuple # 按照原ResultSetMetadata的字段定义namedtuple ResultSetMetadata = namedtuple('ResultSetMetadata', ['name', 'type', 'precision']) # 构造mock列表 mock_desc = [ ResultSetMetadata(name='id', type='', precision=20), ResultSetMetadata(name='name', type='', precision=20) ] mock_cursor.description = mock_desc
如果原类包含更多字段,只需将对应字段名添加到namedtuple的第二个参数列表中。
3. 自定义简单类模拟
编写极简类模拟ResultSetMetadata的结构,灵活性更高:
class ResultSetMetadata: def __init__(self, name, type='', precision=20): self.name = name self.type = type self.precision = precision mock_desc = [ ResultSetMetadata(name='id'), ResultSetMetadata(name='name') ] mock_cursor.description = mock_desc
可根据测试需求随时添加或修改类的属性。
内容的提问来源于stack exchange,提问作者hootowl
相关产品推荐
相关产品推荐

