SqlAlchemy: запрос для поиска json элементов, которые начинаются с подстроки внутри массива - PullRequest
1 голос
/ 13 июля 2020

У меня есть сложный объект json, сохраненный в базе данных postgresql, и я хочу найти все записи, которые содержат или начинаются с подстроки внутри массива. Объект json:

    "configurations" : {
  "CVE_data_version" : "4.0",
  "nodes" : [ {
    "operator" : "OR",
    "cpe_match" : [ {
      "vulnerable" : true,
      "cpe23Uri" : "cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*",
      "versionStartIncluding" : "2.4.0",
      "versionEndIncluding" : "2.4.41"
    } ]
  } ]
}

Точнее, я хочу найти все объекты, которые начинаются с: «cpe: 2.3: a: apache» в поле «cpe23Uri».

Сделанный мной запрос:

session.query(cvemodel.data['configurations']['nodes'][0]['cpe_match'].contains([{'cpe23Uri': 'cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*'}])).all()

Проблема с этим запросом в том, что он соответствует всему слову. Если поставить:

session.query(cvemodel.data['configurations']['nodes'][0]['cpe_match'].contains([{'cpe23Uri': 'cpe:2.3:a:apache:http_server'}])).first()

Ничего не возвращает!

1 Ответ

1 голос
/ 13 июля 2020

Если вы используете PostgreSQL 12 или новее, вы можете использовать jsonb_path_exists() и друзей:

needle = 'cpe:2.3:a:apache:http_server'

session.query(cvemodel).\
    filter(func.jsonb_path_exists(
        cvemodel.data,
        '''$.configurations.nodes[0].cpe_match[*].cpe23Uri ?
           (@ starts with $needle)''',
        json.dumps({"needle": needle}))).\
    all()

Если вы хотите проверить, содержит ли cpe23Uri иглу , вы можете использовать предикат like_regex, особенно если у вас есть stati c "игла"; к сожалению, like_regex принимает только строковые литералы как правый операнд. Другой вариант для запроса «содержит» - извлечь cpe23Uri с помощью jsonb_path_query() или аксессоров и jsonb_array_elements() и использовать традиционный LIKE, как описано здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...