Использование параметров в запросах Data Explorer

Параметры — это мощный инструмент, который можно использовать в запросах Data Explorer на Discourse. Параметры позволяют создавать более динамичные и настраиваемые запросы: вместо того чтобы хардкодить значения в запросах, вы можете объявить переменные, которые будут запрашивать ввод данных при выполнении запроса.

Объявление параметра

Чтобы объявить параметр, вы можете использовать следующий синтаксис:

-- [params]
-- int :parameter_name = 10

Секция параметров в запросе всегда начинается с -- [params], за которым следует каждый тип параметра на новой строке, где parameter_name заменяется именем вашего параметра.

Это создаст поле, в котором вы можете вводить разные значения каждый раз при выполнении запроса.

Типы параметров

При объявлении параметров в ваших запросах Data Explorer вы можете указывать различные типы ввода. Ниже приведены доступные типы параметров и их описания:

Числовые параметры

  • int: Отображает поле ввода числа, становится числовым значением. int ограничен 32-битными числами.
  • bigint: Аналогично int, но может быть больше.
  • double: Разрешает значения с десятичной частью.

Корректность числовых параметров будет проверяться на стороне клиента.

Строковые параметры

  • string: Свободное текстовое поле, становится текстовым значением.

Список параметров

  • int_list: Ввод целых чисел через запятую, становится списком целых чисел через запятую в запросе.
  • string_list: Аналогично int_list, но для строк.

Специфические ID параметры

  • post_id: Числовой ввод; обеспечивает наличие указанного поста на форуме перед выполнением запроса.
  • topic_id: Аналогично post_id, но для тем.
  • badge_id: Обеспечивает наличие указанного бейджа.

Булевы параметры

  • boolean: Отображает флажок.
  • null boolean: Отображает выпадающий список, позволяющий оставить поле пустым.

Параметры времени

  • time: Отображает поле выбора времени.
  • date: Отображает поле выбора даты.
  • datetime: Отображает поле ввода, включающее как дату, так и время.

Параметры селектора

  • user_id: Отображает поле выбора пользователя Discourse и становится числовым ID пользователя.
  • user_list: Аналогично user_id, но позволяет выбрать нескольких пользователей, становясь списком числовых ID пользователей через запятую.
  • group_id: Аналогично user_id, но для групп.
  • group_list: Аналогично user_list, но для групп.
  • category_id: Аналогично user_id, но для категорий.

Внутренние параметры

  • current_user_id: Нет UI для ввода; автоматически устанавливает переменную в ID пользователя, выполняющего запрос.

Использование списковых параметров

При использовании списковых параметров (int_list, string_list, user_list) необходимо проявлять особую осторожность, чтобы избежать синтаксических ошибок. Вот пример правильного использования спискового параметра:

-- [params]
-- user_list :the_user_ids
SELECT SUM(length(bio_raw))
FROM user_profiles
WHERE user_id IN (:the_user_ids)

Нулевые параметры

Вы также можете разрешить пустой ввод, добавив префикс null к типу параметра. Это означает, что при выполнении запроса не обязательно предоставлять значение для этого параметра.

Вот несколько примеров того, как вы можете объявить такие параметры:

-- [params]
-- null int :null_int
-- null boolean :null_boolean
-- null string :null_string
-- null current_user_id :me

В приведенном выше SQL-коде null_int, null_boolean и null_string — это параметры, которые можно оставить пустыми при выполнении запроса.

Давайте посмотрим, как эти типы параметров могут использоваться в запросе:

-- [params]
-- null int :post_id
-- null string :username
SELECT *
FROM users
WHERE (id = :post_id OR :post_id IS NULL)
AND (username = :username OR :username IS NULL)

В этом запросе, если post_id или username не предоставлены (т.е. оставлены как null), запрос проигнорирует эту часть условия WHERE. Это позволяет создавать более гибкие запросы, где некоторые условия являются необязательными.

Валидация на стороне клиента

Большинство типов параметров будут валидироваться на стороне клиента. Эти валидации включают обязательные, но незаполненные поля ввода, некорректный числовой ввод, несуществующие категории или группы, некорректно форматированное время и т.д. Для некорректного ввода причина ошибки будет отображена в форме, и операция выполнения запроса будет отклонена.

Выбор типов и использование приведения типов

В целом, параметры должны «просто работать» в ваших запросах. Для более продвинутых случаев вам может потребоваться добавить явное приведение типа ::type.

Например, для интервалов вам нужно объявить строковый параметр и привести его к типу interval. Значения могут включать единицы измерения, такие как 2 day или 3 hours:

-- [params]
-- string :lookback = 2 day

SELECT id AS topic_id, created_at
FROM topics
WHERE created_at >= NOW() - :lookback::interval

Некоторым функциям также требуются явные типы аргументов:

round(amount::numeric, :decimal_places::integer)
date_trunc('day', :start_date::timestamp)

Дополнительные примеры

Вот несколько дополнительных примеров объявления различных типов параметров:

-- [params]
-- int             :int = 3
-- bigint          :bigint = 12345678912345
-- boolean         :boolean
-- null boolean    :boolean_three = #null
-- string          :string = little bunny foo foo
-- date            :date = 14 jul 2015
-- time            :time = 5:02 pm
-- datetime        :datetime = 14 jul 2015 5:02 pm
-- double          :double = 3.1415
-- string          :inet = 127.0.0.1/8
-- user_id         :user_id = system
-- post_id         :post_id = http://localhost:3000/t/adsfdsfajadsdafdsds-sf-awerjkldfdwe/21/1?u=system
-- topic_id        :topic_id = /t/-/21
-- int_list        :int_list = 1,2,3
-- string_list     :string_list = a,b,c
-- category_id     :category_id = meta
-- group_id        :group_id = admins
-- user_list       :mul_users = system,discobot
-- current_user_id :me 

Другие темы в этой серии

Это отличные руководства, спасибо, что опубликовали их @SaraDev :slight_smile: :hugs:

@AlexDev
Может ли имя поля в предложении WHERE быть параметром? Спасибо.
Или же весь SQL-запрос может быть параметром, передаваемым из REST-эндпоинта /admin/plugin/explorer/queries/id/run?

PSA: Вы не можете использовать цифры в именах параметров, например, «foo123» приведёт к ошибке.

-- [params]
-- string       :foo123 = a

SELECT :foo123

результат:

PG::SyntaxError: ERROR:  syntax error at or near ":"
LINE 10: SELECT :foo123
                ^

Я попытался выполнить POST-запрос к эндпоинту run с параметрами в JSON-теле:

payload = {
    "params": {
        "request_post_id": "45"
    },
    "explain": False
}

Я реверс-инжинирингнул это тело запроса из вкладки Network в инструментах разработчика Chrome.

Почему-то я постоянно получаю ошибку сервера 500.

Может кто-нибудь, пожалуйста, помочь?

PSA: это было недавно добавлено

Запрос функции: Возможно ли добавить тип параметра tag_group, который будет внедрять числовой идентификатор выбранной группы тегов?