Табличная функция executable создаёт таблицу на основе вывода пользовательской функции (UDF), которую вы определяете в скрипте, выводящем строки в stdout. Исполняемый скрипт хранится в каталоге users_scripts и может читать данные из любого источника. Убедитесь, что на ClickHouse server установлены все необходимые пакеты для запуска исполняемого скрипта. Например, если это скрипт на Python, убедитесь, что на server установлены нужные пакеты Python.
При необходимости можно указать один или несколько входных запросов, результаты которых передаются в stdin, чтобы скрипт мог их прочитать.
Синтаксис
Табличная функция executable требует указания трёх параметров и поддерживает необязательный список входных запросов:
executable(script_name, format, structure, [input_query...] [,SETTINGS ...])script_name: имя файла скрипта, сохранённого в папкеuser_scripts(папка по умолчанию для настройкиuser_scripts_path)format: формат создаваемой таблицыstructure: схема создаваемой таблицыinput_query: необязательный запрос (или набор запросов), результаты которого передаются скрипту через stdin
Следующий Python-скрипт называется generate_random.py и сохраняется в папке user_scripts. Он считывает число i и выводит i случайных строк, перед каждой из которых выводится число, отделённое символом табуляции:
#!/usr/local/bin/python3.9
import sys
import string
import random
def main():
# Считать входное значение
for number in sys.stdin:
i = int(number)
# Сгенерировать несколько случайных строк
for id in range(0, i):
letters = string.ascii_letters
random_string = ''.join(random.choices(letters ,k=10))
print(str(id) + '\t' + random_string + '\n', end='')
# Сбросить результаты в stdout
sys.stdout.flush()
if __name__ == "__main__":
main()Давайте запустим скрипт и сгенерируем с его помощью 10 случайных строк:
SELECT * FROM executable('generate_random.py', TabSeparated, 'id UInt32, random String', (SELECT 10))Ответ выглядит следующим образом:
┌─id─┬─random─────┐
│ 0 │ xheXXCiSkH │
│ 1 │ AqxvHAoTrl │
│ 2 │ JYvPCEbIkY │
│ 3 │ sWgnqJwGRm │
│ 4 │ fTZGrjcLon │
│ 5 │ ZQINGktPnd │
│ 6 │ YFSvGGoezb │
│ 7 │ QyMJJZOOia │
│ 8 │ NfiyDDhmcI │
│ 9 │ REJRdJpWrg │
└────┴────────────┘Настройки
send_chunk_header- определяет, отправлять ли количество строк перед передачей фрагмента данных на обработку. Значение по умолчанию —false.pool_size— Размер пула. Если дляpool_sizeуказано значение 0, ограничения на размер пула не применяются. Значение по умолчанию —16.max_command_execution_time— Максимальное время выполнения команды исполняемого скрипта при обработке блока данных. Указывается в секундах. Значение по умолчанию — 10.command_termination_timeout— исполняемый скрипт должен содержать основной цикл с возможностью чтения и записи. После завершения работы табличной функции пайп закрывается, и у исполняемого файла будетcommand_termination_timeoutсекунд на завершение работы, прежде чем ClickHouse отправит дочернему процессу сигнал SIGTERM. Указывается в секундах. Значение по умолчанию — 10.command_read_timeout- тайм-аут чтения данных из stdout команды в миллисекундах. Значение по умолчанию — 10000.command_write_timeout- тайм-аут записи данных в stdin команды в миллисекундах. Значение по умолчанию — 10000.
Передача результатов запроса в скрипт
Обязательно ознакомьтесь с примером для движка таблицы Executable, где показано, как передавать результаты запроса в скрипт. Ниже показано, как выполнить тот же скрипт из этого примера с помощью табличной функции executable:
SELECT * FROM executable(
'sentiment.py',
TabSeparated,
'id UInt64, sentiment Float32',
(SELECT id, comment FROM hackernews WHERE id > 0 AND comment != '' LIMIT 20)
);