Executable 和 ExecutablePool 表引擎允许你定义一个表,其行由你定义的脚本生成 (通过将行写入 stdout) 。可执行脚本存储在 users_scripts 目录中,并且可以从任意源读取数据。
Executable表:每次查询都会运行脚本ExecutablePool表:维护一个持久进程池,并在读取时从池中取出进程
创建 Executable 表
Executable 表引擎需要两个参数:脚本名称和输入数据的格式。你还可以选择传入一个或多个输入查询:
Executable 表的相关设置:
send_chunk_header- 说明:在发送每个 chunk 进行处理之前,先发送该 chunk 中的行数。此设置有助于你以更高效的方式编写脚本,从而预先分配部分资源
- 默认值:false
command_termination_timeout- 说明:命令终止超时时间 (秒)
- 默认值:10
command_read_timeout- 说明:从命令的 stdout 读取数据的超时时间 (毫秒)
- 默认值:10000
command_write_timeout- 说明:向命令的 stdin 写入数据的超时时间 (毫秒)
- 默认值:10000
my_script.py,保存在 user_scripts 文件夹中。它会读取一个数字 i,并打印 i 个随机字符串,每个字符串前面都有一个数字,二者以制表符分隔:
my_executable_table 是基于 my_script.py 的输出构建的;每次从 my_executable_table 执行 SELECT 查询时,都会生成 10 个随机字符串:
my_executable_table 时会调用该脚本:
将查询结果传递给脚本
nltk) ,其中的 SentimentIntensityAnalyzer 可用于判断评论是正面、负面还是中性——并为其赋予一个介于 -1 (非常负面的评论) 到 1 (非常正面的评论) 之间的值。让我们创建一个 Executable 表,使用 nltk 计算 Hacker News 评论的情感倾向。
本示例使用此处所述的 hackernews 表。hackernews 表包含一个类型为 UInt64 的 id 列,以及一个名为 comment 的 String 列。我们先从定义 Executable 表开始:
sentiment 表的一些说明:
- 文件
sentiment.py保存在user_scripts文件夹中 (这是user_scripts_path设置的默认文件夹) TabSeparated格式表示 Python 脚本需要生成原始数据行,其中的值以制表符分隔- 该查询从
hackernews中选择了两列。Python 脚本需要从传入的行中解析出这些列的值
sentiment.py 的定义:
- 要让它正常工作,你需要运行
nltk.downloader.download('vader_lexicon')。这一步本来也可以写进脚本里,但那样每次对sentiment表执行查询时都会重新下载它——这样效率不高 row中的每个值都会对应SELECT id, comment FROM hackernews WHERE id > 0 AND comment != '' LIMIT 20这个查询结果集里的一行- 输入的行是以制表符分隔的,因此我们使用 Python 的
split函数解析出id和comment polarity_scores的结果是一个 JSON 对象,其中包含几个值。我们决定只提取这个 JSON 对象中的compound值- 请注意,ClickHouse 中的
sentiment表使用TabSeparated格式,并且包含两列,因此我们的print函数会用制表符分隔这两列
sentiment 表中选择行的查询时,都会执行 SELECT id, comment FROM hackernews WHERE id > 0 AND comment != '' LIMIT 20 这个查询,并将结果传给 sentiment.py。让我们来试一下:
创建 ExecutablePool 表
ExecutablePool 的语法与 Executable 类似,但 ExecutablePool 表有几个其特有的重要设置:
pool_size- 说明:进程池大小。如果该值为 0,则不限制大小
- 默认值:16
max_command_execution_time- 说明:命令的最大执行时间 (单位:秒)
- 默认值:10
sentiment 表改为使用 ExecutablePool 而非 Executable:
sentiment_pooled 表时,ClickHouse 会按需保持 4 个进程运行。