dbt seedでRedshiftのsuper型にJSONを入れてみた

はじめに

データアナリティクス事業本部のおざわです。 今回はタイトルのとおり、dbt seedコマンドでRedshiftのsuper型のカラムを持つテーブルを作ってJSONデータを入れるというのを試してみました。

super型についてはこちらのブログをご参照ください。

Redshiftは以下ブログ記事にあるCloudFormationテンプレートでRedshift Serverlessを構築しています。

dbtのバージョンは以下のとおりです(dbt debugの結果を一部抜粋)

❯ dbt debug
06:57:06  Running with dbt=1.7.3
06:57:06  dbt version: 1.7.3
06:57:06  adapter type: redshift
06:57:06  adapter version: 1.7.0

1. 結論

結論からお伝えすると、カンマ区切りのCSVではエラーになったため、以下のような対応を行ってseedのテーブルを作ることができました。

  1. delimiterをカンマ(,)からパイプ(|)に変更(パイプでなくてもOK)
  2. CSVの区切り文字も変更

seeds/properties.yml

version: 2

seeds:
  - name: my_super_table_test
    config:
      delimiter: "|"
      column_types:
        id: int
        name: varchar(50)
        device: super

seeds/my_super_table_test.csv

id|name|device
1|Alice|{"type":"phone","hoge":"yay"}
2|Bob|{"type":"tablet"}
3|Charlie|{"type":"laptop"}

2. 試したこと

最初に用意していたCSVです。

seeds/my_super_table_test.csv

id, name, device
1, "Alice", "{\"type\":\"phone\",\"hoge\":\"yay\"}"
2, "Bob", "{\"type\":\"tablet\"}"
3, "Charlie", "{\"type\":\"laptop\"}"

2.1. column_typesの指定

CSVからseedのテーブルを作成する際、なにも指定しなければdbtがCSVの内容からデータ型を推測してテーブルを作成してくれます。公式ドキュメントには、データ型を指定する方法としてdbt_project.ymlを使う方法とproperties.ymlを使う方法が紹介されています。

今回は以下のようなYAMLファイルを作成しました。column_typesでdeviceカラムのデータ型にsuper型を指定しています。

seeds/properties.yml

version: 2

seeds:
  - name: my_super_table_test
    config:
      column_types:
        id: int
        name: varchar(50)
        device: super

この状態でdbt seedを実行すると、カラム数が多すぎるという内容のエラーが出て失敗します。JSONの中にあるカンマをCSVの区切り文字として認識してしまっているようです。

{\"type\":\"phone\",\"hoge\":\"yay\"}

❯ dbt seed
01:44:26  Running with dbt=1.7.3
01:44:27  Registered adapter: redshift=1.7.0
01:44:27  Found 7 models, 1 seed, 7 sources, 0 exposures, 0 metrics, 696 macros, 0 groups, 0 semantic models
01:44:27
01:44:28  Concurrency: 1 threads (target='dev')
01:44:28
01:44:28  1 of 1 START seed file public.my_super_table_test .............................. [RUN]
01:44:28  1 of 1 ERROR loading seed file public.my_super_table_test ...................... [ERROR in 0.02s]
01:44:28
01:44:28  Finished running 1 seed in 0 hours 0 minutes and 1.12 seconds (1.12s).
01:44:28
01:44:28  Completed with 1 error and 0 warnings:
01:44:28
01:44:28    Compilation Error in seed my_super_table_test (seeds/my_super_table_test.csv)
  Row 0 has 4 values, but Table only has 3 columns

Githubに同じエラーに遭遇している人がいましたので、issueのコメントにあったように空白を削除してみたり、他にもエスケープできないか等を試したのですが、上記のエラーは解消できませんでした。

2.2. delimiterの指定

それなら区切り文字を変更できないかと調べたところ、dbtのバージョン1.7からは区切り文字を変更できましたので、以下のようにdelimiterを指定しました。

seeds/properties.yml

version: 2

seeds:
  - name: my_super_table_test
    config:
      delimiter: "|"
      column_types:
        id: int
        name: varchar(50)
        device: super

CSVファイル※の区切り文字も修正して、外側の二重引用符も削除しました。

CSV = Character-Separated Valuesと考えればCSVファイルと呼んでいいはず

seeds/my_super_table_test.csv

id|name|device
1|Alice|{"type":"phone","hoge":"yay"}
2|Bob|{"type":"tablet"}
3|Charlie|{"type":"laptop"}

成功しました

❯ dbt seed
03:38:25  Running with dbt=1.7.3
03:38:25  Registered adapter: redshift=1.7.0
03:38:25  Unable to do partial parsing because a project config has changed
03:38:26  Found 7 models, 1 seed, 7 sources, 0 exposures, 0 metrics, 696 macros,
 0 groups, 0 semantic models
03:38:26
03:38:27  Concurrency: 1 threads (target='dev')
03:38:27
03:38:27  1 of 1 START seed file public.my_super_table_test .............................. [RUN]
03:38:29  1 of 1 OK loaded seed file public.my_super_table_test .......................... [INSERT 3 in 2.16s]
03:38:30
03:38:30  Finished running 1 seed in 0 hours 0 minutes and 3.39 seconds (3.39s).
03:38:30
03:38:30  Completed successfully
03:38:30
03:38:30  Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1

成功すると以下のようにsuper型が設定されたテーブルができていました。

おわりに

以上、dbt seedでRedshiftのsuper型のカラムを持つテーブルを作り、JSONデータを入れてみました。

参考リンク