如何防止Snowflake Python连接器对数组/对象/变量类型列进行json格式化?

如何防止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('

我正在开发一个服务,该服务从Snowflake中提取变量数据并将其公开以供其他地方使用,我希望防止Snowflake连接器转义并添加字符串格式。我尝试的一种方法是使用前面提到的
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)