Python 在SQLAlchemy中使用Postgres索引运算符

Python 在SQLAlchemy中使用Postgres索引运算符,python,postgresql,sqlalchemy,Python,Postgresql,Sqlalchemy,给定具有以下架构的表: 创建表json_数据 id整数主键不为空, 默认_对象VARCHAR10不为空, 数据jsonb不为空 ; 对于表中的每个实体,我希望检索数据['first']['name']字段的值,或者如果它是数据[json_data.default_object]['name']的空值,或者如果后者也是空值,则返回一些默认值。在纯SQL中,我可以编写以下代码来满足我的需要: 插入 json_数据 身份证件 默认_对象, 数据 价值观 0, “默认值”, “{first:{name:

给定具有以下架构的表:

创建表json_数据 id整数主键不为空, 默认_对象VARCHAR10不为空, 数据jsonb不为空 ; 对于表中的每个实体,我希望检索数据['first']['name']字段的值,或者如果它是数据[json_data.default_object]['name']的空值,或者如果后者也是空值,则返回一些默认值。在纯SQL中,我可以编写以下代码来满足我的需要:

插入 json_数据 身份证件 默认_对象, 数据 价值观 0, “默认值”, “{first:{name:first_name_1},默认值:{name:default_name_1}” , 1. “默认值”, “{first:{},default:{name:default_name_2}}” ; 选择 身份证件 合并 json_data.data->“第一个”->“名称”, json_data.data->json_data.default_object->>“name”, “默认值” 作为价值 从…起 json_数据; 我尝试将上述模型转换为SQLAlchemy实体:

将sqlalchemy作为sa导入 从sqlalchemy.dialogs导入postgresql 从sqlalchemy.ext.declarative导入声明性基础 从sqlalchemy.ext.hybrid导入hybrid_属性 Base=声明性的\u Base 类JsonObjectBase: __tablename_uuu='json_数据' id=sa.Columnsa.Integer,主键=True 默认_object=sa.Columnsa.String10,null=False data=sa.Columnpostgresql.JSONB,null=False @杂化性 def nameself->str: obj=self.data.get'first' default\u obj=self.data.getself.default\u对象 如果obj-else-default\u-obj.get'name'或default\u-obj.get'name'返回obj.get'name' @姓名设定器 def nameself,值:str: obj=self.data.setdefault'first',dict obj['name']=值 @name.expression def名称自我: 返回sa.func.coalesce self.data['first','name'].astext, self.data[self.default_对象,'name'].astext, “默认值”, 但混合属性名称的表达式似乎并不像我预期的那样工作。如果我按名称属性查询实体,如:

query=session.queryJsonObject.filterJsonObject.name=='name' SQLAlchemy将查询扩展为如下内容:

选择json_data.id作为json_data_id,选择json_data.default_对象作为json_data_default_对象,选择json_data.data作为json_data_数据 从json_数据 其中coalescejson\u data.data>%data\u 1s,json\u data.data>%data\u 2s,%coalesce\u 1s=%coalesce\u 2s
它使用路径运算符而不是索引运算符。我应该怎么做才能让SQLAlchemy创建一个我在问题开头所写的表达式?

好的,我找到的解决方案非常简单。正如SQLAlchemy文档所述:

索引操作返回一个表达式对象,其类型默认为JSON,因此可以对结果类型调用更多面向JSON的指令

因此,我们可以使用链式python索引操作符。因此,以下代码在我看来是合法的:

类JsonObjectBase: 几乎相同的东西,除了以下内容: @name.expression def名称自我: 返回sa.func.coalesce self.data['first']['name'].astext, self.data[self.default_对象]['name'].astext, “默认值”,
好的,我找到的解决方案非常简单。正如SQLAlchemy文档所述:

索引操作返回一个表达式对象,其类型默认为JSON,因此可以对结果类型调用更多面向JSON的指令

因此,我们可以使用链式python索引操作符。因此,以下代码在我看来是合法的:

类JsonObjectBase: 几乎相同的东西,除了以下内容: @name.expression def名称自我: 返回sa.func.coalesce self.data['first']['name'].astext, self.data[self.default_对象]['name'].astext, “默认值”,
为什么使用路径与索引有关系?看起来您缺少self.data['first','name']中的.astext。对不起,我忘了添加这个。不管怎样,正如您所看到的,SQLAlchemy试图用字符串值替换列名。我现在明白您的意思了。如果它使用路径vs索引,那又有什么关系呢?看起来您缺少self.data['first','name']中的.astext。对不起,我忘了添加这个。无论如何,正如您所看到的,SQLAlchemy试图用字符串值替换列名。我现在明白您的意思了。