Sqlalchemy filter nested jsonb within arrays

匆匆过客 提交于 2019-12-13 17:14:24

问题


I have a Postgres JSONB field, with some nested arrays and other objects.

from sqlalchemy.dialects.postgresql import JSONB


class Family(db.Model):
   meta = db.Column(JSONB)


joes = Family(meta=[
    {
        "name": "Joe",
        "children": [
            {
                "name": "Jane"
            },
            {
                "name": "Kate"
            }
        ]
    },
    {
        "name": "Lisa",
        "children": [
            {
                "name": "Mary"
            },
            {
                "name": "David"
            }
        ]
    },
])

Is there a way to query all the kids with a certain substring in their names?

If I want to query for 'a' it should get me Mary, David, Kate, Jane.

I was thinking, maybe something like

Family.query.filter(
    Family.meta.contains([{"children": [{"name": func.contains("a")}]}])
)

回答1:


The trick is to unnest the array or arrays using jsonb_array_elements(), and then filter:

meta_value = literal_column('meta.value', type_=JSONB)
children_value = literal_column('children.value', type_=JSONB)

Family.query.\
    with_entities(children_value['name'].astext).\
    select_from(
        Family,
        func.jsonb_array_elements(Family.meta).alias('meta'),
        func.jsonb_array_elements(
            meta_value['children']).alias('children')).\
    filter(children_value['name'].astext.contains('a'))

Note the use of literal_column() to reference the values of the set returning function jsonb_array_elements().



来源:https://stackoverflow.com/questions/54669900/sqlalchemy-filter-nested-jsonb-within-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!