本記事が目指すこと
- dbt-coreのOSS活動を実施するにあたり、自作のサブコマンドを作成する方法について紹介する
注意
- 本記事は筆者が所属する会社と関係なく、個人の記事であることをご了承ください
背景
- 筆者は、ちゅらデータ株式会社に務める会社員であるが、就業時間中に職務としてのdbt-coreのOSS活動を始めた(OSS活動自体が初めての経験だった)
- 学びになったことを記事として残す
- dbt1.6のリリースによって、幾つかの追加機能が開発された。
その中で、dbt clone
というサブコマンドも追加されたのだが、そもそもサブコマンドを追加するにあたりどのようなドキュメント、フォルダやファイル、クラスに目を通して作成しなければならないのか気になったので調べてみた。(参考:dbt clone
のPR)
- dbt1.6のリリースによって、幾つかの追加機能が開発された。
本編
初めに読むべきドキュメントとしては、core/dbt/cli/README.md がある。
以下に簡単に内容を紹介する。
core/dbt/cli/main.py
必要なすべてのデコレータおよび新しいコマンドの関数を次のように記述する。
@cli.command("my-new-command")
@requires.postflight
@requires.preflight
def my_new_command(ctx, **kwargs):
...
dbt-coreでは、clickというPythonのパッケージを利用して、CLIを作成している。
そのため、一番上のデコレータ@cli.command("my-new-command")
では、前段に定義したdbt(デコレータ@click.groupで関数cliを修飾したもの)
のサブコマンドとしてmy-new-command
を作成し、関数my_new_command
を修飾しているのである。(なお、サブコマンドはケバブケースで、関数はスネークケースで統一されているようである)
また、@requires.postflight
は、処理の都合上、requiresモジュールのデコレータの中では一番最初に記述される必要があるとのこと。
上記のサンプルはあくまで必要最低限のデコレータのみ記述しているが、core/dbt/cli/main.pyを見れば分かるように、実際には他のいくつかのデコレータを重ねてサブコマンドを定義する。必要に応じて持たせるデコレータを選択すると良い。
core/dbt/cli/types.py
新しいサブコマンドを、Commandクラスに追加する。
ここで、main.pyで定義した関数とサブコマンドをEnumとして以下のように記述する。
class Command(Enum):
MY_NEW_COMMAND = "my-new-command"
core/dbt/cli/flags.py
新しいコマンドを関数command_args
内の辞書に次のように追加する。
types.pyで定義したEnumとmain.pyで定義したサブコマンドの関数を紐づける。
def command_args(command: CliCommand) -> ArgsList:
...
CMD_DICT: Dict[CliCommand, ClickCommand] = {
CliCommand.MY_NEW_COMMAND: cli.my_new_command,
ドキュメントに書かれている新しいサブコマンド追加時の基本項目は以上である。
後は、機能を記述する際には、core/dbt/task
配下に、my_new_command.py
のようなファイルを作成し、MyNewCommandRunner
クラスや、MyNewCommandTask
クラスを作成すれば良い。
また、dbt/tests/util.py
のrun_dbt
関数を利用して、指定したコマンドを実行したときの結果を得ることができるため、テストを作成する際には利用すると良い。
終わりに
ちゅらデータでは、クレイジーな仲間を募集しているでござる
データエンジニア、もしくはSE系からデータエンジニアになりたい方がいればぜひ、御仁の力量に応じたグレード(ジュニア/ミドル/シニア)にて、応募するでござる