如何防止Snowflake Python连接器对数组/对象/变量类型列进行json格式化?
我正在开发一个服务,该服务从Snowflake中提取变量数据并将其公开以供其他地方使用,我希望防止Snowflake连接器转义并添加字符串格式。我尝试的一种方法是使用前面提到的如何防止Snowflake Python连接器对数组/对象/变量类型列进行json格式化?,python,snowflake-cloud-data-platform,Python,Snowflake Cloud Data Platform,我正在开发一个服务,该服务从Snowflake中提取变量数据并将其公开以供其他地方使用,我希望防止Snowflake连接器转义并添加字符串格式。我尝试的一种方法是使用前面提到的converter\u类选项 再深入一点,我发现默认的SnowflakeConverter类根本不执行任何变量/数组/对象转换操作:。既然如此,我对类进行了扩展,将其用作_ARRAY_to_python转换器(首先使用just ARRAY): def将数组转换为python(self,ctx): logger.info('
converter\u类
选项
再深入一点,我发现默认的SnowflakeConverter
类根本不执行任何变量/数组/对象转换操作:。既然如此,我对类进行了扩展,将其用作_ARRAY_to_python转换器(首先使用just ARRAY):
def将数组转换为python(self,ctx):
logger.info('正在尝试转换')
返回lambda x:[s.strip('\“\n\t'),用于x.strip('[\n\t]').split(',')]
使用的conn=connect(user=..,converter\u class=CustomConverter())
其中CustomConverter
如下所示,并执行类似于DefaultConverterClass
函数的操作:
def CustomConverterClass():
converter=sf_lib.connection.DefaultConverterClass()
converter.\u ARRAY\u to\u python=将\u ARRAY\u转换为\u python
回流转换器
我已经检查了conn.converter\u class()。\u ARRAY\u to\u python
和getattr(conn.converter\u class(),“\u ARRAY\u to\u python”的值
建立连接后,它们都匹配前面定义的convert\u array\u to\u python
函数。但是,当我执行查询并检查变量列的游标时:
cursor=conn.cursor(sf_lib.DictCursor)
data=cursor.execute(查询)
对于数据中的行:
...
值仍然被转义。此外,看起来没有调用数组转换器。我可以控制正在查询的表的架构,并已确认该列的类型为ARRAY
雪花连接器似乎使用了json转换。据我所知,通过源代码挖掘,\u ARRAY\u to\u python
调用的调用堆栈应该如下所示:
next(数据)
->JsonDictResult.\uu下一步\uuuu()
->JsonDictResult.\u行到\u python(行)
->\u将数组转换为python(col)
(从)
为什么不在这里调用转换器,我如何防止json格式被应用
我想防止雪花连接器转义和添加字符串格式
实际上,不是Snowflake转义并添加字符串格式。Snowflake connector接收字符串,然后将其转换回其类型。对于Variant,它不进行任何转换,因此您可以使用字符串
为了回答为什么Snowflake不调用converter_类方法的问题,这是因为Snowflake现在使用ApacheArrow来获取查询结果
那么它改变了什么呢?
不再调用方法_json_result_类
实际上,正是这个方法使用converter类来序列化/反序列化结果
简而言之:不再使用converter_类,文档也不是最新的
要测试您的雪花连接器版本是否使用箭头,可以执行以下操作:
from snowflake.connector.cursor import CAN_USE_ARROW_RESULT
print(CAN_USE_ARROW_RESULT)
我没有找到处理Arrow如何反序列化结果的正确方法,我想您需要在迭代结果时将变量列自己转换为dict或list来处理
快速示例:
import json
import snowflake.connector
con = snowflake.connector.connect(
...
)
cursor = con.cursor()
data = cursor.execute("""...""")
def deserialize_sf_value(value):
if isinstance(value, str) and value[0].strip() in '{[':
return json.loads(value)
return value
results = [[deserialize_sf_value(value) for value in row] for row in data]
print(results)
from snowflake.connector.cursor import CAN_USE_ARROW_RESULT
print(CAN_USE_ARROW_RESULT)
import json
import snowflake.connector
con = snowflake.connector.connect(
...
)
cursor = con.cursor()
data = cursor.execute("""...""")
def deserialize_sf_value(value):
if isinstance(value, str) and value[0].strip() in '{[':
return json.loads(value)
return value
results = [[deserialize_sf_value(value) for value in row] for row in data]
print(results)