Некоторые сложные функции Postgres используют операторы, не входящие в стандарт SQL. Одним простым примером является набор операторов POSIX regular expression; Мне нужно, чтобы они включали выражение where where, которое использует границы слов.Использование нестандартных операторов postgres с SQL Korma
Предположим, что я хочу найти виджеты, которые входят в размер 1, где size - это строка, содержащая кодированный json список целых чисел.
Образец данных:
ID Size
1 "[1]"
2 "[1,2,4,12]"
3 "[4,12]"
4 "[2,4]"
Это тривиальное с сырым SQL:
SELECT * FROM widgets WHERE size ~ '\m1\M'
Но становится очень трудно с Корме. Корма позволяет использовать predicates в карте, но функциональность очень ограничительная. Некоторые вещи, которые не работают:
=> (select "widgets" (where {:size ["~" "\\m1\\M"]}))
ClassCastException java.lang.String cannot be cast to clojure.lang.IFn korma.sql.engine/pred-vec (engine.clj:218)
=> (select "widgets" (where {:size [(raw "~") "\\m1\\M"]}))
Failure to execute query with SQL:
SELECT "widgets".* FROM "widgets" WHERE (?) :: [\m1\M]
=> (select "widgets" (where {:size (raw "~ '\\m1\\M'")}))
Failure to execute query with SQL:
SELECT "widgets".* FROM "widgets" WHERE ("widgets"."size" = ~ '\m1\M') :: []
=> (sql-only (select "widgets" (where {:size [(raw "~ '\\m1\\M'")]})))
"SELECT \"widgets\".* FROM \"widgets\" WHERE (NULL)"
осложняющим фактором является то, что другие условия динамически добавляются к карте где после этого один. Поэтому, даже если следующий пример работает, он не допускает строительство этой карты:
=> (sql-only (select "widgets" (where (raw "size ~ '\\m1\\M'"))))
"SELECT \"widgets\".* FROM \"widgets\" WHERE size ~ '\\m1\\M'"
Таким образом, использует нестандартные операторы, такие как ~
выполнить этот матч возможного в Корме в сочетании с картой где? Как бы вы это сделали? Лучшие альтернативы или обходные пути?
Я нашел [YeSQL] (https://github.com/krisajenkins/yesql) блестящим для подобных ситуаций. Он позволяет хранить ваши SQL-запросы, написанные на простом SQL, но обеспечивает действительно опрятный способ вызова их из Clojure. –
Я должен буду помнить YeSQL; для этой стратегии существует много хороших вариантов использования. Тем не менее, похоже, что это не хорошо для динамически генерирующих запросов, что сделало бы его непригодным для этого варианта использования. –