Выражение (параметризованный) ЛЮБОГО (массива) запроса для Postgres в SQLKorma

В настоящее время я использую SQLKorma для проекта, и я сталкиваюсь с небольшим затруднением с ним.

Я построил запрос с двумя левыми соединениями; один из них содержит массив с записями, которые я хочу использовать в моем WHERE пункт.

Это тривиально, чтобы выразить в SQL. Обратите внимание, что это в основном отредактированный запрос.

SELECT
  cu.name,
  c.description,
  c.created_at AT TIME ZONE 'utc'
FROM calendar_users cu LEFT JOIN calendars c ON cu.id = c.user_id
  LEFT JOIN meetings m ON c.id = m.id
WHERE 'status_report' ILIKE ANY (m.meeting_metadata)
GROUP BY m.meeting_metadata, c.created_at, cu.name, cu.description
ORDER BY c.created_at DESC

Доля в отношении ILIKE ANY это то, что я бы хотел перевести на Корму.

Я понимаю из документов, что ANY пункт не поддерживается с WHERE пункт, и я должен изучить использование raw или же exec-raw вместо.

С этим я хочу передать в параметризованный raw строка в WHERE пункт, чтобы выполнить то, что я пытаюсь пойти.

Это я пытался, но это не с синтаксической ошибкой в ​​Postgres:

(select calendars
    (fields calendar-user-cols)
    (join :calendar_users (= :calendars.user_id :calendar_users.id))
    (join :meetings (= :calendars.id :meetings.id))
    (where (raw ["? ILIKE ANY(meetings.meeting_metadata)" metadata])))

В частности:

PSQLException:
 Message: ERROR: syntax error at or near "["
  Position: 1006
 SQLState: 42601
 Error Code: 0

Как бы я пошел по этому поводу, используя Korma? Нужно ли прибегать к полномасштабному exec-raw запрос?

1 ответ

Решение

Корма имеет очень полезную функцию korma.core/sql-only который будет отображать строку SQL, которая будет выполнена.

(defentity calendars)
=> #'korma-test.core/calendars

(sql-only
  (select calendars
          (fields :x :y)
          (join :calendar_users (= :calendars.user_id :calendar_users.id))
          (join :meetings (= :calendars.id :meetings.id))
          (where (raw ["? ILIKE ANY(meetings.meeting_metadata)" "status_report"]))))
=> "SELECT \"calendars\".\"x\", \"calendars\".\"y\" FROM (\"calendars\" LEFT JOIN \"calendar_users\" ON \"calendars\".\"user_id\" = \"calendar_users\".\"id\") LEFT JOIN \"meetings\" ON \"calendars\".\"id\" = \"meetings\".\"id\" WHERE [\"? ILIKE ANY(meetings.meeting_metadata)\" \"status_report\"]"

или более читаемый:

SELECT "calendars"."x",
       "calendars"."y"
FROM ("calendars"
      LEFT JOIN "calendar_users" ON "calendars"."user_id" = "calendar_users"."id")
LEFT JOIN "meetings" ON "calendars"."id" = "meetings"."id"
WHERE ["? ILIKE ANY(meetings.meeting_metadata)" "status_report"]

как видите, ILIKE окружен [], Корма-х raw просто принимает необработанную строку и не поддерживает параметризацию, такую ​​как exec-raw делает. Вектор вокруг строки ILIKE был просто превращен в строку с ее содержимым. Вот почему вы получили сообщение Postgres об [,

Вы должны удалить [] из строки ILIKE, если вы хотите продолжать использовать rawили посмотреть, если exec-raw будет соответствовать вашим потребностям лучше. Существует очень реальная опасность внедрения SQL-кода, если вы используете "сырье", хотя вам нужно будет обойтись.

;; require clojure.string :as str in your ns
;; change your clause from
(where (raw ["? ILIKE ANY(meetings.meeting_metadata)" "status_report"])))
;; to this
(where (raw (str/join " " ["'status_report'" "ILIKE ANY(meetings.meeting_metadata)"])))
Другие вопросы по тегам