Я пытаюсь использовать Postgresql LTREE с knex.
Чтобы управлять им, я должен использовать необработанные запросы knex, потому что, очевидно, LTREE не является родным в knex (это специфично для postgresql)
Оператором в postgresql и LTREE является символ ?
, в knex.raw символ ?
используется для привязки значений (как всем известно), поэтому возникает конфликт.
Еще раз, это не такпроблема, потому что мы можем использовать \\?
для предотвращения замены значений, когда knex находит ?
в необработанном запросе.
Моя проблема в том, что мне нужно выполнить «SELECT EXISTS» моего запроса, содержащего knex.raw с символом \\?
, а в knex я использую: knex.raw(myQuery).wrap('SELECT EXISTS(', ')')
, чтобы выполнить SELECT EXISTS.Итак, у меня есть вложенные необработанные запросы, один для выбора существует и один в myQuery
для условия postgresql ltree.
Во время выполнения запроса первый knex.raw преобразует исходный \\?
в => ?
, что нормально, и второй knex.raw будет выполнять ту же работу, он найдет ?
и захочет связать данные, но я не даю ему данные, и поэтому knex выдает ошибку !!!
Решение состоит в том, чтобы поместить \\\\?
вместо \\?
, при этом первый knex.raw преобразует запрос с помощью \\?
, а второй knex.raw преобразует окончательный запрос с ?
, чтоэто то, что я хочу в postgresql (не пытаясь делать привязки)
Это здорово!Но myQuery
генерируется универсальной функцией, которая вызывается в контексте с SELECT EXISTS, но также в контексте без SELECT EXISTS, и если я добавлю \\\\?
только с одним knex.raw (контекст без SELECT EXISTS), он также выдастошибка postgresql на этот раз (потому что postgresql не может распознать \\?
).
Можно ли экранировать символ `?` Через все knex.raw?
Плохое (но работающее) решение - установить параметр для функции, которая генерирует запрос кточно, если это контекст вложенных необработанных запросов или нет.
edit:
Вот простой пример кода, который мы можем иметь:
const functionThatCreatesTheSubQuery = () => {
const condition = knex.raw('columnWithLTree \\? array["Root.Noeud1"]::lquery[]');
return this.where(condition);
};
knex.raw(
knex.select('property')
.from('table')
.where(functionThatCreatesTheSubQuery())
).wrap('SELECT EXISTS (', ')');
Это не получается, потому чтопервый knex.raw удаляет первый двойной \\
из \\?
, а второй knex.raw для .wrap будет ожидать привязки