【dbt+Snowflake】dbtを使って日本語テーブル名をよしなにSnowflake上へ作りたい
はじめに
Snowflakeで日本語テーブルをよしなに受け入れてもらえて嬉しいが、
dbtで実装するならどうしよう・・・と迷うことがありました。
そんな悩みを dbtのconfigブロックにあるdatabase,schema,alias
を使い解決したので備忘録として載せておきます。
なるべく日本語テーブルは作りたくは無いが、、どうしてもdbtを使って日本語テーブルの作成が必要な方はぜひ見てください。
事前準備
- dbt or dbt Cloud:PJの作成が終わっていること
- Snowflake
- ユーザ・RSAキーペア
私はdbt Cloudで作業しますが、dbt-core+任意エディタでも再現可能です。
無邪気に日本語テーブルを作って落としてみる
まずは無邪気に作ってみましょう。
touch models/日本語テーブル.sql
この状態で下記を記述し、dbt build --select 日本語テーブル
します。
{{ config(materialized="table") }}
with
final as (
select 1
union
select 2
)
select *
from final
結果を見てみるとちゃんと落ちますね。
せっかくなので原因も見ておきましょう
落ちる原因と解決策
日本語テーブルにおける二重引用符の問題
dbtの実行ログを見ていると下記の部分が怪しそうです。
Reason: Database Error in model 日本語テーブル (models/日本語テーブル.sql)
001003 (42000): 01b83557-0001-eca4-0000-2c7902c39c16: SQL compilation error:
syntax error line 1 at position 63 unexpected '.'.
compiled code at target/run/jaffle_shop_streamlit/models/日本語テーブル.sql.
ここでわかるのが、実行時のsqlで構文エラーになってますね。原因箇所を見てみます。
create or replace transient table pte_k_hamaguchi_dbt_cloud.RAW.日本語テーブル
as
( ...
二重引用符無しで通ってますね。これではダメです。
解決策
aliasを入れましょう。
{{ config(materialized="table", alias='"日本語テーブル"') }}
with
final as (
select 1
union
select 2
)
select *
from final
無事に通りましたね。
runで作成されるファイルも見ておきます。
create or replace transient table pte_k_hamaguchi_dbt_cloud.RAW."日本語テーブル"
as
( ...
二重引用符がちゃんとついています。
冪等性がない問題
上記で安心して再度実行すると下記のようなエラーが出ます。
08:36:38 Marking all children of 'model.jaffle_shop_streamlit.日本語テーブル' to be skipped because of status 'error'. Reason: Compilation Error in model 日本語テーブル (models/日本語テーブル.sql)
When searching for a relation, dbt found an approximate match. Instead of guessing
which relation to use, dbt will move on. Please delete "PTE_K_HAMAGUCHI_DBT_CLOUD"."LAKE"."日本語テーブル", or rename it to be less ambiguous.
Searched for: PTE_K_HAMAGUCHI_DBT_CLOUD.RAW."日本語テーブル"
Found: "PTE_K_HAMAGUCHI_DBT_CLOUD"."RAW"."日本語テーブル"
> in macro materialization_table_snowflake (macros/materializations/table.sql)
> called by model 日本語テーブル (models/日本語テーブル.sql).
ここでわかるのが、
どうやらdbtは PTE_K_HAMAGUCHI_DBT_CLOUD.LAKE."日本語テーブル"
というdbt側の管理idで探しているが、
見つけたのは"PTE_K_HAMAGUCHI_DBT_CLOUD"."LAKE"."日本語テーブル"
と全てに二重引用符がついた別の管理idだったよという話ですね。
とても似ていますが、これでは別物なのでエラーを吐きます。
解決策
configで二重引用符のDB名とSchema名を追加しましょう!
{{
config(
database='"PTE_K_HAMAGUCHI_DBT_CLOUD"',
schema='"RAW"',
alias='"日本語テーブル"',
materialized="table",
)
}}
with
final as (
select 1
union
select 2
)
select *
from final
これで何度buildしても大丈夫になります!
念の為・・・Snowflakeでも確認しておきましょう!!
(しっかり存在してますね〜)
さいごに
力技ですが、dbtのログを見ながら日本語テーブルを無事Snowflake上にデプロイしました!
日本語テーブルを作らないといけない人は是非試してみてください。
以上hamaでした〜
Discussion