0

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?

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.