简体   繁体   中英

Update single element in jsonb column with sqlalchemy core

I have a jsonb column in a table, where each element is of the form

{id: str, value: bool}

I'd like to update a single (or list of) element(s) matching an ID. Is there an idiomatic way to do so using sqlalchemy core (not ORM), without reading and writing the whole column, or constructing sql queries by hand?

Based on this answer , given this initial setup:

tbl = sa.Table(
    't71821876',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('stuff', JSONB),
)

tbl.drop(engine, checkfirst=True)
tbl.create(engine)

with engine.begin() as conn:
    ins = tbl.insert()
    conn.execute(
        ins, [{'stuff': {'id': str(n), 'value': False}} for n in range(3)]
    )

We can do the update with jsonb_set * like this:

with engine.begin() as conn:
    stmt = (
        sa.update(tbl)
        .where(tbl.c.stuff['id'].astext == '0')
        .values(
            stuff=sa.func.jsonb_set(tbl.c.stuff, '{value}', json.dumps(True))
        )
    )
    conn.execute(stmt)

The other answer on that page could be translated to

with engine.begin() as conn:
    stmt = (
        sa.update(tbl)
        .where(tbl.c.stuff['id'].astext == '1')
        .values(stuff=tbl.c.stuff + json.dumps({'id': '1', 'value': True}))
    )
    conn.execute(stmt)

but it replaces the column in the selected row(s) so presumably does not meet your criteria.


* Postgresql JSON functions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM