python - 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 但获得 VARCHAR(8905) 列 DATA
转储生成的 json:
"[{\"component\":null,\"display_name\":\"blah\",\"key\":null,\"row\":{\"display_name\":\"blah\",\"type\":\"blah\"},\"sub_type\":null,\"type\":\"blah\"}]"
或者,尝试在不执行 json.dumps 的情况下分配列表:
sqlalchemy.exc.ProgrammingError:(snowflake.connector.errors.ProgrammingError)252004:无:处理pyformat参数失败;'dict' 对象没有属性 'replace'
解决方案
据我所知,你正在尝试的目前是不可能的。我遇到了同样的问题,尽管我对SQLAlchemy 自定义类型有相当多的了解,但我目前无法解决它。
问题如下:
- 要插入
VARIANT
列,您需要使用 Snowflake 函数PARSE_JSON
。 - 要使用所述功能,您需要在
SELECT
子句的上下文中,即您不能将其与INSERT ... VALUES
格式一起使用(请参阅Snowflake Community)
我不知道有任何方法可以强制 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;
推荐阅读
- java - 错误:无法从 Selenium 中的 NUMERIC 单元格获取 STRING 值
- python - pyinstaller制作的程序运行失败
- flutter - 在 Flutter 中将数据从一个小部件列表添加到另一个列表
- unity3d - Gitlab-Runner Shell 自动删除文件
- ios - SwiftUI - 此代码是否实例化了一个新的场景对象?
- javascript - 即使我的代码是正确的,为什么当我尝试 npm start 时我的 electron.js 应用程序不会打开?
- python - Python-Bitcoinlib - FileNotFoundError:找不到模块'libeay32'
- c - 拆分C链表而不复制
- python - Linux中Python子进程之间管道的困难
- networking - K8s 是否在普通的 Layer2 网络基础设施上运行?