🍵

【dbt+Snowflake】dbtを使って日本語テーブル名をよしなにSnowflake上へ作りたい

2024/12/25に公開

はじめに

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