![[新機能]dbt CloudのCopilot機能でMarkdownのスタイルガイドを自動生成できるようになりました](https://images.ctfassets.net/ct0aopd36mqt/wp-thumbnail-f846b6052d1f7b983172226c6b1ed44b/6b4729aabfb5b7a3359acc27dc6b5453/dbt-1200x630-1.jpg)
[新機能]dbt CloudのCopilot機能でMarkdownのスタイルガイドを自動生成できるようになりました
さがらです。
dbt Cloudの新機能として、Copilot機能でMarkdownのスタイルガイドを自動生成できるようになりました。
この機能を試してみたので、その内容を本記事でまとめてみます。
※2025/6/11追記:後日改めて検証したところ結果が変わったため、内容を大幅に修正しております。
Copilot機能でMarkdownのスタイルガイドを自動生成
まず、Copilot機能でMarkdownのスタイルガイドを自動生成してみます。
Studioを開き、dbt Copilotのボタンを押したら、Style guide
を押します。
すると、下図のような形でdbt-styleguide.md
というファイルを自動で生成してくれます。
内容としては下記になります。
## Naming fields and tables
- The primary key of a model should be named `<object>_id`, for example, `account_id`. This makes it easier to know what `id` is being referenced in downstream joined models.
- Consistency is key! Use the same field names across models where possible. For example, a key to the `customers` table should be named `customer_id` rather than `user_id` or `id`.
- Do not use abbreviations when naming fields. Emphasize readability over brevity. For example, do not use `cust` for `customer` or `o` for `orders`.
- Avoid reserved words as column names.
- Booleans should be prefixed with `is_` or `has_`.
- Timestamp columns should be named `<event>_at`(for example, `created_at`) and should be in UTC. If a different timezone is used, this should be indicated with a suffix (`created_at_pt`).
- Dates should be named `<event>_date`. For example, `created_date.`
- Table, CTE, and column names should be written in `snake_case`.
## Styling SQL
- Use trailing commas.
- Indents should be four spaces.
- Field names, keywords, and function names should all be lowercase.
- The `as` keyword should be used explicitly when aliasing a field or table.
- Grouped fields should be stated before aggregates and window functions in the select list
- Aggregations should be executed as early as possible (on the smallest data set possible) before joining to another table to improve performance.
- Ordering and grouping by a number (eg. group by 1, 2) is preferred over listing the column names explicitly
- Prefer `union all` to `union` unless you explicitly want to remove duplicates.
- If joining two or more tables, _always_ qualify your column names with the relevant table name. If only selecting from one table, qualification is not needed.
- Be explicit about your join type (i.e. write `inner join` instead of `join`).
- Do not use right joins ever. Do not use full outer joins unless you really need to.
- All references to other dbt models, seed, or snapshots should use the {{ ref() }} dbt function
- All references to dbt sources should use the {{ source() }} dbt function
- Do not use or call dbt macros unless you are explicitly instructed to
- Do not re-alias CTE names.
- Do not use short table aliases like `select * from orders as o` -- always prefer longer, explicit table aliases or no aliases at all. `select * from orders` is better.
## Styling Jinja
- When using Jinja delimiters, use spaces on the inside of your delimiter, like `{{ this }}` instead of `{{this}}`
## Styling YAML
- Indents should be two spaces
- List items should be indented
- Use a new line to separate list items that are dictionaries where appropriate
- 日本語翻訳版
## フィールドとテーブルの命名規則
- モデルの主キーは `<object>_id`(例: `account_id`)のように命名する必要があります。これにより、下流で結合されるモデルでどの `id` が参照されているかが分かりやすくなります。
- 一貫性が重要です!可能な限り、モデル間で同じフィールド名を使用してください。例えば、`customers` テーブルへのキーは `user_id` や `id` ではなく `customer_id` と命名すべきです。
- フィールドの命名に略語を使用しないでください。簡潔さよりも読みやすさを重視してください。例えば、`customer` に `cust`、`orders` に `o` を使用しないでください。
- 予約語を列名として使用することは避けてください。
- ブール値のフィールドには `is_` または `has_` の接頭辞を付けます。
- タイムスタンプの列は `<event>_at`(例: `created_at`)と命名し、UTCであるべきです。異なるタイムゾーンを使用する場合は、接尾辞で示す必要があります(例: `created_at_pt`)。
- 日付の列は `<event>_date` と命名すべきです。例: `created_date`。
- テーブル、CTE、および列名は `snake_case` で記述する必要があります。
## SQLのスタイル
- 末尾にカンマを使用します。
- インデントは4つのスペースにします。
- フィールド名、キーワード、関数名はすべて小文字にします。
- フィールドやテーブルにエイリアスを付ける際は `as` キーワードを明示的に使用します。
- グループ化されたフィールドは、`select` リスト内で集計関数やウィンドウ関数の前に記述します。
- パフォーマンス向上のため、集計は他のテーブルに結合する前に、できるだけ早い段階で(可能な限り最小のデータセットで)実行します。
- 列名を明示的にリストアップするよりも、番号による順序付けやグループ化(例: `group by 1, 2`)が推奨されます。
- 明示的に重複を削除したい場合を除き、`union` よりも `union all` を使用します。
- 2つ以上のテーブルを結合する場合は、*常に*列名を関連するテーブル名で修飾してください。1つのテーブルからのみ選択する場合は、修飾は不要です。
- joinの種類を明示的にしてください(つまり `join` の代わりに `inner join` と書きます)。
- `right join` は絶対に使用しないでください。本当に必要な場合を除き、`full outer join` は使用しないでください。
- 他のdbtモデル、seed、またはsnapshotへのすべての参照は、`{{ ref() }}` dbt関数を使用する必要があります。
- dbtソースへのすべての参照は、`{{ source() }}` dbt関数を使用する必要があります。
- 明示的に指示されない限り、dbtマクロを使用したり呼び出したりしないでください。
- CTE名を再エイリアスしないでください。
- `select * from orders as o` のような短いテーブルエイリアスは使用しないでください。常に、より長く明示的なテーブルエイリアスを使用するか、エイリアスをまったく使用しないことを推奨します。`select * from orders` の方が良いです。
## Jinjaのスタイル
- Jinjaの区切り文字を使用する場合、`{{this}}` ではなく `{{ this }}` のように、区切り文字の内側にスペースを使用します。
## YAMLのスタイル
- インデントは2つのスペースにします。
- リスト項目はインデントします。
- 辞書であるリスト項目を区切るには、必要に応じて改行を使用します。
この生成されたdbt-styleguide.md
を保存すると、プロジェクトのルート階層に保存されます。
Copilotが生成するSQLへの影響を確認
次に、dbt-styleguide.md
によってCopilotが生成するSQLへの影響があるかを確認してみます。
進め方
意味があるかはわからないのですが、Copilotの履歴を一度クリアするため、dbt-styleguide.md
に変更を加えたら、一度ブラウザを更新してStudioの画面を再読込し、その後にCopilot機能でSQLを生成してみます。
dbt-styleguide.md
をそのまま利用
生成された生成されたdbt-styleguide.md
をそのまま利用したときに、Copilotが生成するSQLに差があるかを確認してみます。
依頼内容は下記の文章となります。(余談ですが、@からモデル名を指定できるようになっています。)
stg_customersと stg_ordersを結合して、orderごとにcustomerの情報を紐づけたデータを作りたいです
結果としては下記のようになり、dbt-styleguide.md
有無によって出力するSQLに差は出ませんでした。
dbt-styleguide.md
なし
with customers as (
select
customer_id,
first_name,
last_name
from {{ ref('stg_customers') }}
),
orders as (
select
order_id,
customer_id,
order_date,
status
from {{ ref('stg_orders') }}
)
select
o.order_id,
o.order_date,
o.status,
c.customer_id,
c.first_name,
c.last_name
from orders o
inner join customers c on o.customer_id = c.customer_id
dbt-styleguide.md
あり ※スタイルガイドはデフォルト出力のまま
with customers as (
select
customer_id,
first_name,
last_name
from {{ ref('stg_customers') }}
),
orders as (
select
order_id,
customer_id,
order_date,
status
from {{ ref('stg_orders') }}
)
select
o.order_id,
o.order_date,
o.status,
c.customer_id,
c.first_name,
c.last_name
from orders o
inner join customers c on o.customer_id = c.customer_id
dbt-styleguide.md
を日本語にして内容をカスタマイズして利用
次にdbt-styleguide.md
を日本語にして内容をカスタマイズした上で、Copilot機能を使ってみます。
以下が変更した後のdbt-styleguide.md
になります。日本語とした以外に生成物に影響がある変更点は2箇所で、「SQLのスタイル」で「インデントは8つのスペースにします。」と「SQLキーワードと関数名はすべて大文字にします。」に変更しています。
## フィールドとテーブルの命名規則
- モデルの主キーは `<object>_id`(例: `account_id`)のように命名する必要があります。これにより、下流で結合されるモデルでどの `id` が参照されているかが分かりやすくなります。
- 一貫性が重要です!可能な限り、モデル間で同じフィールド名を使用してください。例えば、`customers` テーブルへのキーは `user_id` や `id` ではなく `customer_id` と命名すべきです。
- フィールドの命名に略語を使用しないでください。簡潔さよりも読みやすさを重視してください。例えば、`customer` に `cust`、`orders` に `o` を使用しないでください。
- 予約語を列名として使用することは避けてください。
- ブール値のフィールドには `is_` または `has_` の接頭辞を付けます。
- タイムスタンプの列は `<event>_at`(例: `created_at`)と命名し、UTCであるべきです。異なるタイムゾーンを使用する場合は、接尾辞で示す必要があります(例: `created_at_pt`)。
- 日付の列は `<event>_date` と命名すべきです。例: `created_date`。
- テーブル、CTE、および列名は `snake_case` で記述する必要があります。
## SQLのスタイル
- 末尾にカンマを使用します。
- インデントは8つのスペースにします。
- フィールド名、キーワード、関数名はすべて大文字にします。
- フィールドやテーブルにエイリアスを付ける際は `as` キーワードを明示的に使用します。
- グループ化されたフィールドは、`select` リスト内で集計関数やウィンドウ関数の前に記述します。
- パフォーマンス向上のため、集計は他のテーブルに結合する前に、できるだけ早い段階で(可能な限り最小のデータセットで)実行します。
- 列名を明示的にリストアップするよりも、番号による順序付けやグループ化(例: `group by 1, 2`)が推奨されます。
- 明示的に重複を削除したい場合を除き、`union` よりも `union all` を使用します。
- 2つ以上のテーブルを結合する場合は、*常に*列名を関連するテーブル名で修飾してください。1つのテーブルからのみ選択する場合は、修飾は不要です。
- joinの種類を明示的にしてください(つまり `join` の代わりに `inner join` と書きます)。
- `right join` は絶対に使用しないでください。本当に必要な場合を除き、`full outer join` は使用しないでください。
- 他のdbtモデル、seed、またはsnapshotへのすべての参照は、`{{ ref() }}` dbt関数を使用する必要があります。
- dbtソースへのすべての参照は、`{{ source() }}` dbt関数を使用する必要があります。
- 明示的に指示されない限り、dbtマクロを使用したり呼び出したりしないでください。
- CTE名を再エイリアスしないでください。
- `select * from orders as o` のような短いテーブルエイリアスは使用しないでください。常に、より長く明示的なテーブルエイリアスを使用するか、エイリアスをまったく使用しないことを推奨します。`select * from orders` の方が良いです。
## Jinjaのスタイル
- Jinjaの区切り文字を使用する場合、`{{this}}` ではなく `{{ this }}` のように、区切り文字の内側にスペースを使用します。
## YAMLのスタイル
- インデントは2つのスペースにします。
- リスト項目はインデントします。
- 辞書であるリスト項目を区切るには、必要に応じて改行を使用します。
この状態で、先程と同じリクエスト文を投げてみます。
stg_customersと stg_ordersを結合して、orderごとにcustomerの情報を紐づけたデータを作りたいです
すると、スタイルガイドに記載した通り、SQLキーワードと関数名はすべて大文字、インデントは8つのスペースで、出力されました!(なぜかWITH句の使い方も最初と異なる使い方になって、1つのWITH句でJOINまで行う仕様になりました。)
WITH customer_orders AS (
SELECT
customers.customer_id,
customers.customer_name,
orders.order_id,
orders.order_date,
orders.total_amount
FROM
{{ ref('stg_customers') }} AS customers
INNER JOIN
{{ ref('stg_orders') }} AS orders
ON
customers.customer_id = orders.customer_id
)
SELECT
*
FROM
customer_orders
最後に
dbt CloudのCopilot機能でMarkdownのスタイルガイドを自動生成できるようになりましたので、その内容を試してみました。
スタイルガイドを参照してCopilotがSQLを生成してくれるのが良いですね!ぜひご活用ください!