§ Incremental updates of
PostgreSQL JSONB columns
– How to “update” an
hierarchy of nested objects
by merging with the existing
value?
– Solution: wrote a custom
helper that generates SQL
value expression
Technical issues with SQLAlchemy
def sql_json_merge(
col,
key: Tuple[str, ...],
obj: Mapping[str, Any],
*,
_depth: int = 0,
):
expr = sa.func.coalesce(
col if _depth == 0 else col[key[:_depth]],
sa.text("'{}'::jsonb"),
).concat(
sa.func.jsonb_build_object(
key[_depth],
(
sa.func.coalesce(col[key], sa.text("'{}'::jsonb"))
.concat(sa.func.cast(obj, psql.JSONB))
if _depth == len(key) - 1
else sql_json_merge(col, key, obj=obj, _depth=_depth + 1)
)
)
)
return expr
sa.update(tbl).values(status_data=sql_json_merge(
tbl.c.status_data,
("scheduler",),
{"last_try": datetime.now(tzutc()).isoformat(),
"passed_predicates": ["concurrency", "keypair_resource_policy"]},
)
{
"scheduler": {
"first_try": "2021-05-01T02:01:01.00Z",
"last_try": "2021-05-01T02:03:04.55Z",
"passed_predicates": ["concurrency"],
}
}
16