BigQueryのUDFをTypeScriptで書く
BigQueryのUDFをTypeScriptで書く方法の備忘録。
サンプルをGitHubに置いたので、中で何をやっているかを簡単にメモしておく。
普段からJavaScriptを書く人ではないので、間違ったことも書いているかもしれない。
ざっくり
- WebPackによって、tsをjsにコンパイルして1ファイルにまとめる
- そのファイルの内容をUDFの定義文字列の中に挿入する
各ファイルの意味(主要部だけ)
ソースファイル
sql/greet.jinja.sql
#standardSQL
create temp function greet(name string)
returns string
language js as
"""
{% include "greet.js" %}
return greet.greet(name);
""";
select greet("World");
UDFの定義を書いたファイル。が、本質的な部分はテンプレート化され、外部のgreet.js
というファイルから読み込むようになっている。
WebPackによって、このファイルがTypeScriptのソースから作成されるようにする。
src/main.ts
import { Hello } from "./Hello";
export function greet(name: string): string{
const h = new Hello(name);
return h.greet();
}
greet
という関数をexport
している。このファイルが上のSQLで参照されているファイル(greet.js
)にコンパイルされるように、WebPackその他の設定ファイルを作る。
単体テストのコードについては省略。
設定ファイル
package.json
開発に必要なライブラリと、ビルド・テストコマンドなどを書いておくところ。npm run XXX
とすると、このjsonの"scripts"
から対応するコマンドを探して実行する。
package-lock.json
npm install
した際に実際にダウンロードされたパッケージとバージョンの記録。開発環境を完璧に再現するために使われる。
tsconfig.json
tsからjsへのコンパイル時に参照される設定、だと思うが、その意味はよく分かってない。
webpack-config.js
複数ファイルをまとめて1つのファイルにするための設定集。大事なところは
-
mode
:production
にしておく。develop
としてもパッケージングはできるが、出来上がったコードにコメントなどが含まれてしまい、SQLに埋め込んだときに問題となる -
entry
: 実行対象となる関数のソースファイルへのパス -
path
: 出来上がるファイルのファイルの置き場所 -
filenaem
: 出来上がるファイルのファイル名 -
library
: ライブラリオブジェクトの名前 -
libraryTargt
:var
を指定しておく。これによって、var ... =
で始まるjsファイルが生成される(...
にはlibrary
の値が入る)。
Makefile
普段、JavaScriptを触らないので、コマンドの備忘を兼ねてMakefileが置いてある。
.PHONY: load prepare build test clean
load: dist/greet.sql
cat $< | bq query
dist/%.sql: sql/%.jinja.sql build
cp $< dist
jinja2 $(subst sql/,dist/,$<) > $@
build:
npm run build
test:
npm run test
prepare:
npm i
clean:
rm -rf dist
動作確認
$ git clone https://github.com/hotoku/bigquery-udf-typescript.git
$ cd bigquery-udf-typescript
$ make prepare # npm installが走る
$ make test # 単体テストを実行する
$ make load # コンパイル・UDF定義への埋め込みを実行し、BigQueryにクエリを投げる
注意:生成されるJSコードをSQLに埋め込むためにjinja2を使っている(pip install jinja-cli
でインストールできる)。
単体テストについて
chai/mochaというフレームワークを利用している。これについては、ここでは書かない。