Snowflake:Sqlalchemy ORM更新变体字段



我在使用sqlalchemy更新表示雪花中的表的python模型时遇到问题。其中一列是变量字段,当我尝试更新模型并将其保存回数据库时,雪花会抱怨该值不是变量。我尝试过将数据作为字典和json字符串传递,但都不起作用。

模型属性定义为:

data = db.Column(snowsql.VARIANT)

snowsql是snowflake-sqlalchemy包的别名,该包已安装,但它似乎只提供类型方言,没有提供太多其他内容。

有人有做这件事的经验吗?

更新:

我添加的数据是字典的python列表:

new_data['data'] = [{'component': None, 'display_name': 'blah', 'key': None, 'row': {'display_name': 'blah', 'type': 'blah'}, 'sub_type': None, 'type': 'blah'}]

设置变量属性时执行json.dumps:

new_blah = Blah(
data = json.dumps(new_data['data'])
)

结果:

表达式类型与列数据类型不匹配,应为VARIANT,但得到列data 的VARCHAR(8905(

转储产生的json:

"[{"component":null,"display_name":"blah","key":null,"row":{"display_name":"blah","type":"blah"},"sub_type":null,"type":"blah"}]"

或者,尝试在不执行json.dumps:的情况下分配列表

sqlalchemy.exc.ProgramingError:(snowflake.connector.errors.ProgrammingError(252004:无:处理pyformat参数失败;'dict对象没有属性"replace">

据我所知,您目前正在尝试的是不可能的。我也遇到了同样的问题,尽管我对SQLAlchemy自定义类型有很大的了解,但我目前无法解决它

问题如下:

  1. 要插入VARIANT列,需要使用Snowflake函数PARSE_JSON
  2. 要使用上述函数,您需要在SELECT子句的上下文中,即不能将其与INSERT ... VALUES格式一起使用(请参阅Snowflake社区(

我不知道有任何方法可以强制SQLAlchemy创建子查询,因为这是必需的。

如果这种情况在未来发生变化,以下是我的进展:

class SnowflakeJSON(TypeDecorator):
impl = VARIANT
def process_bind_param(self, value, dialect):
return json_serialize(value)
def process_result_value(self, value, dialect):
return json_deserialize(value)
def bind_expression(self, bindparam):
return func.PARSE_JSON(bindparam, type_=self)
def copy(self, **kw):
return SnowflakeJSON()

这会生成一个查询,如:

INSERT INTO my_table (key, data) 
VALUES ('001', PARSE_JSON('{"test": "hello world"}'));

然而,根据上面的雪花社区条目,VALUES格式不起作用,您需要以下格式:

INSERT INTO my_table (key, data) 
SELECT '001', PARSE_JSON('{"test": "hello world"}');

作为后备,您可以始终使用一种列类型,将JSON对象存储为VARCHAR:

class SnowflakeJSON(TypeDecorator):
impl = String
def process_bind_param(self, value, dialect):
return json_serialize(value)
def process_result_value(self, value, dialect):
return json_deserialize(value)
def copy(self, **kw):
return SnowflakeJSON()

这样一来,您显然会失去将JSON字符串存储为VARIANT数据类型的好处。然而,您可以在稍后阶段对此进行解析,甚至在查询中也是如此:

SELECT PARSE_JSON(text)['test'] from my_table;

相关内容

  • 没有找到相关文章

最新更新