gpt4 book ai didi

python - 如何使用python api代码仅更新postgres表中json类型列的1个属性

转载 作者:行者123 更新时间:2023-11-29 12:16:38 25 4
gpt4 key购买 nike

我有一个名为 products 的 postgresql(v.9.5) 表,使用 sqlalchemy 核心定义为:

products = Table("products", metadata,
Column("id", Integer, primary_key=True),
Column("name", String, nullable=False, unique=True),
Column("description", String),
Column("list_price", Float),
Column("xdata", JSON))

假设表格中的日期添加如下:

id |    name    |        description        | list_price |             xdata              
----+------------+---------------------------+------------+--------------------------------
24 | Product323 | description of product332 | 6000 | [{"category": 1, "uom": "kg"}]

使用API​​编辑代码如下:

def edit_product(product_id):
if 'id' in session:
exist_data = {}
mkeys = []
s = select([products]).where(products.c.id == product_id)
rs = g.conn.execute(s)
if rs.rowcount == 1:
data = request.get_json(force=True)
for r in rs:
exist_data = dict(r)
try:
print exist_data, 'exist_data'
stmt = products.update().values(data).\
where(products.c.id == product_id)
rs1 = g.conn.execute(stmt)
return jsonify({'id': "Product details modified"}), 204
except Exception, e:
print e
return jsonify(
{'message': "Couldn't modify details / Duplicate"}), 400

return jsonify({'message': "UNAUTHORIZED"}), 401

假设我只想修改表的 xdata 列中的“category”值,而不影响“uom”属性及其值,哪种方法最好?我已经尝试过“for 循环”来获取现有值的属性,然后检查传递的属性值更改以进行更新。我相信有比这更好的方法。请恢复简化此操作所需的更改

最佳答案

Postgresql 提供函数 jsonb_set()用新值替换 jsonb 的一部分。您的专栏使用的是 json 类型,但一个简单的转换就可以解决这个问题。

from sqlalchemy.dialects.postgresql import JSON, JSONB, array
import json

def edit_product(product_id):
...

# If xdata is present, replace with a jsonb_set() function expression
if 'xdata' in data:
# Hard coded path that expects a certain structure
data['xdata'] = func.jsonb_set(
products.c.xdata.cast(JSONB),
array(['0', 'category']),
# A bit ugly, yes, but the 3rd argument to jsonb_set() has type
# jsonb, and so the passed literal must be convertible to that
json.dumps(data['xdata'][0]['category'])).cast(JSON)

您还可以设置一个通用帮助程序,它创建对 jsonb_set() 的嵌套调用,给定一些结构:

import json

from sqlalchemy.dialects.postgresql import array

def to_jsonb_set(target, value, create_missing=True, path=()):
expr = target

if isinstance(value, dict):
for k, v in value.items():
expr = to_jsonb_set(expr, v, create_missing, (*path, k))

elif isinstance(value, list):
for i, v in enumerate(value):
expr = to_jsonb_set(expr, v, create_missing, (*path, i))

else:
expr = func.jsonb_set(
expr,
array([str(p) for p in path]),
json.dumps(value),
create_missing)

return expr

但这可能有点过头了。

关于python - 如何使用python api代码仅更新postgres表中json类型列的1个属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50506358/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com