Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Cloud のユーザー定義関数

ユーザー定義関数 (UDF) を使用すると、ClickHouse に標準で用意されている 1,000 種類を超える 関数 だけでは対応できない処理を追加できます。

ClickHouse Cloud では、ユーザー定義関数を作成および管理する方法がいくつかあります。

  1. SQL を使用する
  2. UI と独自のコードを使用する (公開ベータ)
  3. Cloud API を使用する (ベータ)
  4. Terraform を使用する (ベータ)

SQL ユーザー定義関数

SQL UDF は、ラムダ式を使って CREATE FUNCTION ステートメントで作成できます。

この例では、シンプルな実行可能ユーザー定義関数 isBusinessHours を作成します。 この関数は、特定のタイムスタンプが通常の営業時間内かどうかを確認し、該当すれば true、そうでなければ false を返します。

  1. Cloud Console にログインし、SQL コンソールを開きます
  2. 次の SQL クエリを入力して isBusinessHours 関数を作成します:
CREATE FUNCTION isBusinessHours AS (ts) ->
toDayOfWeek(ts) BETWEEN 1 AND 5
AND toHour(ts) BETWEEN 9 AND 17;
  1. 新しく作成したUDFをテストするには、以下を実行します。
SELECT isBusinessHours('2026-03-20 10:00:00'::DateTime), isBusinessHours('2026-03-20 23:00:00'::DateTime);

次の結果が返されるはずです:

1   0
  1. DROP FUNCTION コマンドを使って、先ほど作成した UDF を削除できます。
DROP FUNCTION isBusinessHours

これは、次のことを意味します。

  • セッションレベルの設定 (SET ステートメントで設定したもの) は、UDF の実行コンテキストには引き継がれません
  • ユーザープロファイルの設定は UDFs に継承されません
  • クエリレベルの設定は UDF の実行中には適用されません

UI で作成するユーザー定義関数

ベータ機能

ClickHouse Cloud では、UI からユーザー定義関数を作成できます。

この例では、特定の timestamp が通常の営業時間内かどうかを判定する、前回と同じシンプルな実行可能ユーザー定義関数 isBusinessHours を作成します。 前回は SQL を使って作成しましたが、今回は Python で実装し、UI から設定します。

Python ファイルを作成する

ローカルで新しいファイル main.py を作成します。

cat > main.py << 'EOF'
import sys
from datetime import datetime

for line in sys.stdin:
    ts = datetime.fromisoformat(line.strip())
    result = 1 if (0 <= ts.weekday() <= 4 and 9 <= ts.hour <= 17) else 0
    print(result)
    sys.stdout.flush()
EOF

Python スクリプトでサードパーティ製パッケージをインポートする場合は、それらを requirements.txt ファイルに記載すれば、ClickHouse Cloud がインストールしてくれます。代わりに依存関係を ZIP に直接含めることもできますが、その場合は両方の CPU アーキテクチャ向けにキャッシュ済みのパッケージを含める必要があるため、requirements.txt を使うほうが簡単です。たとえば、次のようになります。

requests>=2.28.0
numpy>=1.23.0

依存関係パッケージとローカルファイルをまとめる

依存関係パッケージや追加のローカルファイル (wheel ファイル、設定ファイル、データファイルなど) を含めるには、main.pyrequirements.txt と同じディレクトリに配置します。ZIP アーカイブを作成する際は、すべてのファイルを含めてください。

zip is_business_hours.zip main.py requirements.txt

Python コードでは、os.path.dirname(os.path.abspath(__file__)) を使って、ローカルにバンドルされた path のベース directory を参照できます。これにより、ZIP アーカイブ内で main.py が配置されている directory の絶対 path が返され、バンドルされたほかのファイルにアクセスできるようになります。

import os

# Get the base directory of the bundled files
base_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(base_dir, 'config.json')

これは、次のような場合に便利です:

  • UDF に含まれている構成ファイルにアクセスする
  • カスタム依存関係の wheel パッケージを読み込む
  • 追加のスクリプトやデータファイルを参照する

次に、ファイルを ZIP アーカイブに圧縮します:

zip is_business_hours.zip main.py

UI で UDF を作成する

  1. Cloud コンソールのホームページで、左下のメニューにある組織名をクリックします。
  2. メニューから ユーザー定義関数 を選択します。
  3. ユーザー定義関数ページで UDF を設定 をクリックします。画面右側に設定パネルが開きます。
  4. 関数名を入力します。この例では isBusinessHours を使用します。
  5. 関数タイプとして Executable pool または Executable を選択します。
    • Executable pool: 永続的なプロセスのプールが維持され、読み取り時にはそのプールからプロセスが割り当てられます。
    • Executable: スクリプトはクエリごとに実行されます。
  6. この例では、デフォルト設定を使用します。設定パラメーターの一覧については、Executable user-defined functions を参照してください。
  7. ファイルを参照 をクリックして、このチュートリアルの冒頭で作成した .zip ファイルをアップロードします。
  8. 新しい引数を追加します。この例では、型 DateTime の引数 timestamp を追加します。
  9. 戻り値の型を選択します。この例では Bool を選択します。
  10. UDF を作成 をクリックします。現在のビルドステータスを示すダイアログが表示されます。
    • 問題がある場合、ステータスは error に変わります。
    • 問題がなければ、ステータスは building から provisioning に進みます。プロビジョニングを完了するには、サービスが稼働中である必要があります。サービスがアイドル状態の場合は、サービス名の横にある UDF details パネルで Wake Up Service をクリックします。
    • 完了すると、ステータスは deployed に変わります。

UDFをテストする

  1. ページ左上の Settings - return to your service view をクリックして、SQL Console のホーム画面に戻ります
  2. 左側のメニューで SQL Console をクリックします
  3. 次のクエリを入力します:
SELECT isBusinessHours('2026-03-20 10:00:00'::DateTime), isBusinessHours('2026-03-20 23:00:00'::DateTime);

以下の結果が表示されるはずです。

true    false

新しいバージョンを作成する

UDF のコードを変更するには、新しいバージョンを作成します。Edit パネルで管理できるのは、UDF をどのサービスに割り当てるかだけです。そこでファイルをアップロードしても、デプロイ済みのコードは置き換えられません。

  1. Cloud Console のホーム画面で、左下のメニューにある組織名をクリックします。
  2. メニューから User-defined functions を選択します。
  3. isBusinessHours UDF の Actions にある 3 点メニューを選択し、Create new version をクリックします
  4. 変更したコードを含む zip をアップロードするか、設定を変更してから Create new version をクリックします

これで、UI から最初のユーザー定義関数を追加し、それが実行されることを確認し、必要に応じて新しいバージョンを作成する方法も確認できました。

Cloud API を使用して UDF を管理する

ベータ機能

UI で利用できるすべての機能は、ClickHouse Cloud API を通じてプログラムからも利用できます。 UDF エンドポイントを使用すると、ソースアーカイブのアップロード、関数とバージョンの作成、サービスへのアタッチ、削除まで、UDF のライフサイクル全体をスクリプトで自動化できます。

API を介した UDF の作成とデプロイの一般的なワークフローは次のとおりです。

  1. 署名付き application/zip アップロード URL を取得するためにアップロード URL を作成し、その URL に ZIP アーカイブをアップロードします。各アップロード ID は、作成またはバージョン作成の 1 回の試行にのみ使用できます。再試行する場合は、新しいアップロード URL をリクエストしてください。
  2. アップロードしたアーカイブから UDF を作成し、関数名、ランタイム、引数、戻り値の型を指定します。
  3. UDF をサービスにアタッチします。バージョンを省略した場合は、最新の準備完了バージョンがアタッチされます。サービスは実行中である必要があります。アイドル状態のサービスは事前に起動できます。

エンドポイントの一覧は次のとおりです。

エンドポイント 説明
UDF アップロード URL を作成 組織スコープの署名付き application/zip アップロード URL を作成します
UDF を作成 アップロードしたアーカイブから新しい UDF を作成します
UDF を一覧表示 組織内の各 UDF の最新バージョンを返します
UDF を取得 UDF の最新バージョンを返します
UDF を削除 UDF のすべてのバージョンを削除し、すべてのサービスからデタッチします
UDF バージョンを作成 ソースアーカイブを使用してバージョンを割り当て、UDF のビルドを開始します
UDF バージョンを一覧表示 UDF のすべてのバージョンを返します
UDF バージョンを削除 どのサービスにもアタッチされていない UDF バージョンを削除します
UDF をサービスにアタッチ 必要に応じて現在のバージョンを置き換え、UDF の 1 つのバージョンをサービスにアタッチします
UDF アタッチメントを一覧表示 UDF の現在のサービスへのアタッチ状況を返します
UDF アタッチメントを取得 指定したサービスへの UDF の現在のアタッチ状況を返します
UDF をサービスからデタッチ UDF をサービスからデタッチします

リクエストおよびレスポンスのスキーマについては、UDF API リファレンスを参照してください。

Terraform で UDF を管理する

ベータ機能

公式の ClickHouse Terraform プロバイダーには、Infrastructure as Code として UDF を管理するためのリソースが 2 つ含まれています。

  • clickhouse_udfは、関数自体を管理します。関数のソースコードを含む ZIP アーカイブを受け取り、アーカイブのハッシュが変更されるたびに新しいバージョンをパブリッシュし、ビルドの完了を待機します。
  • clickhouse_udf_attachmentは、UDF のバージョンをサービスにアタッチします。サービスに関連付けられる関数のバージョンは、一度に最大 1 つです。固定のバージョン番号を指定することも、clickhouse_udf.<name>.version を参照してサービスを最新バージョンに自動更新することもできます。

たとえば、前の例の isBusinessHours UDF を Terraform でデプロイするには、次のようにします。

resource "clickhouse_udf" "is_business_hours" {
  function_name = "isBusinessHours"
  runtime       = "python3.11"
  type          = "executable_pool"
  return_type   = "Bool"

  arguments = [
    { name = "timestamp", type = "DateTime" },
  ]

  source_archive_path = "${path.module}/is_business_hours.zip"
  source_archive_hash = filebase64sha256("${path.module}/is_business_hours.zip")
}

resource "clickhouse_udf_attachment" "production" {
  function_name = clickhouse_udf.is_business_hours.function_name
  service_id    = var.service_id
  version       = clickhouse_udf.is_business_hours.version
}

アタッチは準備完了のバージョンに対してのみ成功し、完了まで数分かかる場合があります。アイドル状態のサービスは自動的に起動します。clickhouse_udf リソースを削除すると、関数のすべてのバージョンが削除され、すべてのサービスからデタッチされます。

Navigation