サマリー
- dbt が Treasure Data で動くか試してみた。
- 結果としては dbt-presto の修正が必要そうで現状のままでは動作しないことが確認できた。
- 果たして dbt-presto に Treasure Data に合うようなモードを追加するのが良いか、 dbt-athena のように別なプラグインとして提供するのが良いか。
dbt on Presto
以前の記事で少し触れたように dbt は Presto 用のプラグイン dbt-presto を用意しており、現時点では一部機能のみ使用することが可能である。
Due to the nature of Presto, not all core dbt functionality is supported. The following features of dbt are not implemented on Presto: 1. Snapshots 2. Incremental models
Trino でも問題なく動くようだ。
Trino + dbt = a match in SQL heaven? | by Victor Coustenoble | Geek Culture | Medium
動作確認手順
インストール
dbt, dbt-presto をインストールし、プロジェクトを作成する。
$ python3 -m venv venv $ source venv/bin/activate $ pip install dbt-presto $ dbt --version installed version: 0.20.0 latest version: 0.20.0 Up to date! Plugins: - presto: 0.20.0 $ dbt init dbt-td-sample --adapter presto Running with dbt=0.20.0 Creating dbt configuration folder at /Users/satoshi.hirose/.dbt With sample profiles.yml for presto Your new dbt project "dbt-td-sample" was created! If this is your first time using dbt, you'll need to set up your profiles.yml file (we've created a sample file for you to connect to presto) -- this file will tell dbt how to connect to your database. You can find this file by running: open /Users/satoshi.hirose/.dbt For more information on how to configure the profiles.yml file, please consult the dbt documentation here: https://docs.getdbt.com/docs/configure-your-profile One more thing: Need help? Don't hesitate to reach out to us via GitHub issues or on Slack -- There's a link to our Slack group in the GitHub Readme. Happy modeling!
接続情報の追加
Treasure Data への接続方法を確認しながら ~/.dbt/profiles.yml を修正する。
JDBC Driver for Presto - Product Documentation - Treasure Data Product Documentation
td: target: dev outputs: dev: type: presto method: none # optional, one of {none | ldap | kerberos} user: <your api key> password: dummy database: td-presto host: api-presto.treasuredata.com port: 443 schema: satoshihirose threads: 1
dbt debug の実行
dbt debug を試してみるとエラーが発生する。
$ cd dbt-td-sample $ dbt debug --profile td Running with dbt=0.20.0 dbt version: 0.20.0 python version: 3.9.6 python path: /Users/satoshi.hirose/work/dbt-td-sample/venv/bin/python3.9 os info: macOS-11.2.3-x86_64-i386-64bit Using profiles.yml file at /Users/satoshi.hirose/.dbt/profiles.yml Using dbt_project.yml file at /Users/satoshi.hirose/work/dbt-td-sample/dbt-td-sample/dbt_project.yml Configuration: profiles.yml file [OK found and valid] dbt_project.yml file [OK found and valid] Required dependencies: - git [OK found] Connection: host: api-presto.treasuredata.com port: 443 user: 7060/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx database: td-presto schema: satoshihirose Connection test: ERROR dbt was unable to connect to the specified database. The database returned the following error: >Runtime Error error 400: b'<html>\r\n<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>\r\n<body>\r\n<center><h1>400 Bad Request</h1></center>\r\n<center>The plain HTTP request was sent to HTTPS port</center>\r\n</body>\r\n</html>\r\n' Check your database credentials and try again. For more information, visit: https://docs.getdbt.com/docs/configure-your-profile
どうやら https で接続していないことが問題のようだ。
確認をすると dbt-presto は auth が none の時は http 接続をするようハードコードされており、設定などでは対応できないようだ。プラグインのコードを https に書き換えて先に進む。
接続することは確認できた。
(venv) [/Users/satoshi.hirose/work/dbt-td-sample/dbt-td-sample]dbt debug --profile td Running with dbt=0.20.0 dbt version: 0.20.0 python version: 3.9.6 python path: /Users/satoshi.hirose/work/dbt-td-sample/venv/bin/python3.9 os info: macOS-11.2.3-x86_64-i386-64bit Using profiles.yml file at /Users/satoshi.hirose/.dbt/profiles.yml Using dbt_project.yml file at /Users/satoshi.hirose/work/dbt-td-sample/dbt-td-sample/dbt_project.yml Configuration: profiles.yml file [OK found and valid] dbt_project.yml file [OK found and valid] Required dependencies: - git [OK found] Connection: host: api-presto.treasuredata.com port: 443 user: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx database: td-presto schema: satoshihirose Connection test: OK connection ok
dbt run の実行
次は dbt run を実行してみるとエラーが発生する。トランザクション周りで問題が発生している。
(venv) [/Users/satoshi.hirose/work/dbt-td-sample/dbt-td-sample]dbt run --profile td Running with dbt=0.20.0 Found 2 models, 4 tests, 0 snapshots, 0 analyses, 145 macros, 0 operations, 0 seed files, 0 sources, 0 exposures Encountered an error: Runtime Error Runtime Error PrestoUserError(type=USER_ERROR, name=NOT_SUPPORTED, message="Nested transactions not supported", query_id=20210727_130455_32322_s2qyv)
デバッグログを確認してみると、information schema は取得できているっぽいが、start transaction が失敗しているっぽい。TD のコンソールでクエリの実行状況を見ても同様の事象が確認できる。
$ dbt --debug run --profile td ... 2021-07-27 13:05:20.472157 (MainThread): Acquiring new presto connection "model.my_new_project.my_first_dbt_model". 2021-07-27 13:05:20.480174 (MainThread): Acquiring new presto connection "model.my_new_project.my_second_dbt_model". 2021-07-27 13:05:20.539955 (MainThread): Sending event: {'category': 'dbt', 'action': 'load_project', 'label': '728c6762-9aca-4330-bc3b-3840456a8980', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x10ceeac40>]} 2021-07-27 13:05:20.543735 (MainThread): Sending event: {'category': 'dbt', 'action': 'resource_counts', 'label': '728c6762-9aca-4330-bc3b-3840456a8980', 'context': [<snowplow_tracker.self_describing_json.SelfDescribingJson object at 0x10ceead00>]} 2021-07-27 13:05:20.543977 (MainThread): Found 2 models, 4 tests, 0 snapshots, 0 analyses, 145 macros, 0 operations, 0 seed files, 0 sources, 0 exposures 2021-07-27 13:05:20.544701 (MainThread): 2021-07-27 13:05:20.544973 (MainThread): Acquiring new presto connection "master". 2021-07-27 13:05:20.545602 (ThreadPoolExecutor-0_0): Acquiring new presto connection "list_td-presto". 2021-07-27 13:05:20.555404 (ThreadPoolExecutor-0_0): Using presto connection "list_td-presto". 2021-07-27 13:05:20.555564 (ThreadPoolExecutor-0_0): On list_td-presto: select distinct schema_name from "td-presto".INFORMATION_SCHEMA.schemata 2021-07-27 13:05:20.555703 (ThreadPoolExecutor-0_0): Opening a new connection, currently in state init 2021-07-27 13:05:27.149112 (ThreadPoolExecutor-0_0): SQL status: OK in 6.59 seconds 2021-07-27 13:05:27.153038 (ThreadPoolExecutor-0_0): On list_td-presto: Close 2021-07-27 13:05:27.154223 (ThreadPoolExecutor-1_0): Acquiring new presto connection "list_td-presto_satoshihirose". 2021-07-27 13:05:27.159687 (ThreadPoolExecutor-1_0): Opening a new connection, currently in state closed 2021-07-27 13:05:28.579790 (ThreadPoolExecutor-1_0): Error while running: handle.start_transaction() 2021-07-27 13:05:28.580094 (ThreadPoolExecutor-1_0): PrestoUserError(type=USER_ERROR, name=NOT_SUPPORTED, message="Nested transactions not supported", query_id=20210727_130528_32356_s2qyv) 2021-07-27 13:05:28.580380 (ThreadPoolExecutor-1_0): Error while running: macro list_relations_without_caching 2021-07-27 13:05:28.580660 (ThreadPoolExecutor-1_0): Runtime Error PrestoUserError(type=USER_ERROR, name=NOT_SUPPORTED, message="Nested transactions not supported", query_id=20210727_130528_32356_s2qyv) 2021-07-27 13:05:28.581073 (ThreadPoolExecutor-1_0): On list_td-presto_satoshihirose: Close ...
どうやら TD が start transaction をサポートしていないのが原因のようだ。
プラグインの start transaction を発行している箇所をコメントアウトして実行してみる。
dbt-presto/connections.py at cc834028f8120784829cc66733007dbabcec1a30 · dbt-labs/dbt-presto · GitHub
先に進んだ。次は、View が作れないことが原因のエラーのようだ。
$ dbt run --profile td Running with dbt=0.20.0 Found 2 models, 4 tests, 0 snapshots, 0 analyses, 145 macros, 0 operations, 0 seed files, 0 sources, 0 exposures 22:14:14 | Concurrency: 1 threads (target='dev') 22:14:14 | 22:14:14 | 1 of 2 START table model satoshihirose.my_first_dbt_model............ [RUN] 22:14:22 | 1 of 2 OK created table model satoshihirose.my_first_dbt_model....... [OK in 8.54s] 22:14:22 | 2 of 2 START view model satoshihirose.my_second_dbt_model............ [RUN] 22:14:24 | 2 of 2 ERROR creating view model satoshihirose.my_second_dbt_model... [ERROR in 1.47s] 22:14:24 | 22:14:24 | Finished running 1 table model, 1 view model in 16.26s. Completed with 1 error and 0 warnings: Runtime Error in model my_second_dbt_model (models/example/my_second_dbt_model.sql) PrestoUserError(type=USER_ERROR, name=NOT_SUPPORTED, message="This connector does not support creating views", query_id=20210727_131423_32607_s2qyv) Done. PASS=1 WARN=0 ERROR=1 SKIP=0 TOTAL=2
TD は View をサポートしていないため、View ではなくテーブルを作成するように設定を変更する。
dbt_project.yml の materialized の箇所を view から table に書き換える。
models: my_new_project: # Applies to all files under models/example/ example: materialized: table
dbt run の実行に成功した。
dbt run --profile td Running with dbt=0.20.0 Found 2 models, 4 tests, 0 snapshots, 0 analyses, 145 macros, 0 operations, 0 seed files, 0 sources, 0 exposures 22:17:24 | Concurrency: 1 threads (target='dev') 22:17:24 | 22:17:24 | 1 of 2 START table model satoshihirose.my_first_dbt_model............ [RUN] 22:17:33 | 1 of 2 OK created table model satoshihirose.my_first_dbt_model....... [OK in 8.63s] 22:17:33 | 2 of 2 START table model satoshihirose.my_second_dbt_model........... [RUN] 22:17:40 | 2 of 2 OK created table model satoshihirose.my_second_dbt_model...... [OK in 7.42s] 22:17:40 | 22:17:40 | Finished running 2 table models in 27.49s. Completed successfully Done. PASS=2 WARN=0 ERROR=0 SKIP=0 TOTAL=2
コンソールを確認すると、サンプルのテーブルが作成されていることがわかる。
二つのテーブルが作成された。 テーブルに追加されたデータ。
結果としては dbt-presto の修正が必要そうで現状のままでは動作しないことが確認できた。
修正が必要な箇所は
- http 接続がハードコードされている箇所
- start transaction が実行される箇所
1 は新しいモードを追加することで簡単に修正できそうである。2 については、設定などで start transaction の実行を回避できないか調査していたが、dbt 本体にも実行を指定している箇所があるなど簡単な修正では対応できないように感じた。果たして dbt-presto に Treasure Data に合うようなモードを追加するのが良いか、 dbt-athena のように別なプラグインとして提供するのが良いか。