SqlAlchemy(Flask + Postgres):如何只更新json字段的特定属性?

时间:2016-03-09 16:57:15

标签: python json postgresql sqlalchemy flask-sqlalchemy

我有一个表,其中一列声明为json,我需要通过向json值添加键值来更新记录。

模型

class User(db.Model):

    __tablename__ = 'users'

    loginId         = db.Column(db.String(128),  nullable=False, primary_key=True)
    _password       = db.Column(db.String(128),  nullable=True)
    views           = db.Column(JSON,         nullable=True)

控制器

@mod_event.route('/view', methods=['POST'])
def view():
    try:
        params = request.json
        loginId = params['dream']['loginId']
        users.update().\
            where(users.c.loginId==loginId).\
            values(views=<query>))

假设views中的当前值为{&#39; 1001&#39; :1} 如果必须将views更新为 -

,那么查询应该是什么
  • {&#39; 1001&#39; :2}
  • {&#39; 1001&#39; :1,&#39; 1002&#39; :1}

如果我不想先查询该值,请更改并更新回来。

我很难在单个查询中查明如何执行此操作,请帮助,谢谢!

3 个答案:

答案 0 :(得分:1)

有关如何在SQL中执行此操作,请参阅this answer

在Python中做同样的事情(使用PostgreSQL 9.5):

update().where(...)\
    .values(views=cast(cast(u.c.views, JSONB)
                       .concat(func.jsonb_build_object('1002', 1)), JSON)

对于PostgreSQL 9.3+,您必须首先在PostgreSQL中创建该函数,然后:

update().where(...)\
    .values(views=func.json_object_set_key(u.c.views, '1002', 1))

答案 1 :(得分:1)

如果您使用JSONB,则可以使用jsonb_set功能

(table
 .update()
 .values(views=func.jsonb_set(table.c.views,
                              '{%s}' % '1002',
                              1))
 .where(...))

如果您从其他列插入

(table
 .update()
 .values(views=func.jsonb_set(table.c.views,
                              '{%s}' % '1002',
                             other_table.c.other_column.cast(String).cast(JSONB)))
 .where(...))

答案 2 :(得分:0)

这样我们就可以在视图字段中更新新的键值对。

users.query.filter(users.c.loginId==loginId).update({users.data: cast(
        cast(users.data, JSONB).concat(func.jsonb_build_object('1002', 1)), JSON)}, synchronize_session="fetch")