extends でのコードの再利用

これは、LookML に関する確かな知識がある読者向けの高度なトピックです。

概要

LookML モデルのサイズと複雑さが増すにつれて、LookML の複数の場所での再利用に役立つようになります。extends パラメータを使用すると、コードを再利用できます。これにより、次のことが可能になります。

  • DRY(繰り返しを避けること)コードを記述すると、1 か所ですべてを定義でき、コードの整合性が高まり、迅速に編集できるようになります
  • ユーザーごとに異なるフィールド セットを管理する
  • プロジェクトのさまざまな部分でデザイン パターンを共有する
  • プロジェクト全体で結合、ディメンション、メジャーのセットを再利用する

LookML オブジェクトを拡張するには、新しい LookML オブジェクトを作成し、extends パラメータを追加して、新しいオブジェクトが既存のオブジェクトの拡張であることを示します。つまり、プロジェクトに LookML オブジェクトの 2 つのバージョンが存在することになります。競合がある場合は、拡張するオブジェクトが優先され、拡張されるオブジェクトの設定をオーバーライドします。詳しくは、このページの extends の実装の詳細をご覧ください。

LookML の絞り込みを確認する: ビューや Explore の拡張は、複数のバージョンのビューや Explore を使用する場合に最適です。ただし、目標がビューや Explore を含む LookML ファイルを編集せずに単にビューや Explore を変更をすることである場合は、代わりに絞り込みを使用することをおすすめします。絞り込みで extends パラメータを使用することもできます。詳細とユースケースについては、LookML の絞り込みのドキュメント ページをご覧ください。

ビュー、Explore、LookML ダッシュボードを拡張できます。

モデルを拡張することはできず、モデルファイルを別のモデルファイルに含めることもできません。モデル間で Explore を再利用または拡張する場合は、別の Explore ファイルを作成してから、その Explore ファイルをモデルファイルに含めます

Explore の拡張LookML ダッシュボードの拡張の例を参照してください。

Explore の拡張

Explore の拡張の例を次に示します。

explore: customer {
  persist_for: "12 hours"
}

explore: transaction {
  extends: [customer]
  persist_for: "5 minutes"
}

この例では、[Customer] という Explore と、それを拡張する [Transaction] という 2 つ目の Explore を作成しました。結合など、[Customer] 内にあるすべてのものが [Transaction] に含まれます。[Transaction] に含まれる項目はすべて [Transaction] に残ります。

ただし、競合が存在することがわかります。[Customer] Explore では persist_for の設定が 12 時間になっているはずですが、[Transaction] Explore では 5 分と表示されています。[Transaction] Explore では persist_for: "5 minutes" 設定が使用されます。拡張される Explore の設定が上書きされるためです。

LookML ダッシュボードの拡張

LookML ダッシュボードを拡張するには、拡張されるダッシュボードと拡張するダッシュボードの両方をモデルファイルに含める必要があります。extends パラメータを使用するダッシュボードが、拡張するベース ダッシュボードのないモデルファイルに含まれている場合、ベースダッシュボードが見つからないという LookML 検証エラーが表示されます。

ダッシュボード ファイルの例を次に示します。

ファイル: faa.dashboard.lookml

- dashboard: faa
  title: FAA Dashboard
  layout: newspaper
  elements:
  - title: Aircraft Location
    name: Aircraft Location
    model: e_faa
    explore: aircraft
    type: looker_map
    fields:
    - aircraft.zip
    - aircraft.count
    sorts:
    - aircraft.count desc
    limit: 500
    query_timezone: America/Los_Angeles
    series_types: {}
    row: 0
    col: 0
    width: 8
    height: 6

新しい LookML ダッシュボード ファイルを作成し、新しいタイルを追加して FAA ダッシュボードを拡張できます。

ファイル: faa_additional.dashboard.lookml

- dashboard: faa_additional
  title: FAA Additional
  extends: faa
  elements:
  - title: Elevation Count
    name: Elevation Count
    model: e_faa
    explore: airports
    type: looker_scatter
    fields:
    - airports.elevation
    - airports.count
    sorts:
    - airports.count desc
    limit: 500
    query_timezone: America/Los_Angeles
    row: 0
    col: 8
    width: 8
    height: 6

[FAA] ダッシュボードが拡張されるため、[FAA Additional] ダッシュボードには、faa.dashboard.lookml ファイルで定義されているタイルがすべて含まれます。また、[FAA Additional] ダッシュボードには、独自の faa_additional.dashboard.lookml ファイルで定義されているすべてのタイルが含まれます。

LookML ダッシュボードを作成する最も簡単な方法は、ユーザー定義のダッシュボードから LookML を取得することです。この手法を使用して、個々のダッシュボード タイルの LookML を取得することもできます。この方法を使用する場合は、タイルの位置が重ならないようにしてくださいfaa.dashboard.lookmlfaa_additional.dashboard.lookml の例では、タイルは両方ともダッシュボードの一番上の行にあり、row: 0 で示されます。

ファイル: faa.dashboard.lookml


    row: 0
    col: 0
    width: 8
    height: 6

ただし、[FAA Additional] ダッシュボードに追加する新しいタイルは col: 8 にあるため、拡張ダッシュボードのタイルの横に表示されます。

ファイル: faa_additional.dashboard.lookml


    row: 0
    col: 8
    width: 8
    height: 6

これらの要素は異なるダッシュボード ファイルに存在するため、見落としがちです。したがって、拡張されるダッシュボードにタイルを追加する場合は、拡張されるダッシュボード内のタイルと拡張するダッシュボード内のタイルとの間の位置競合をチェックしてください。

必要な拡張機能

LookML オブジェクトを拡張機能が必要としてフラグを付けるには、extension: required パラメータを使用します。つまり、オブジェクトを単独で使用することはできません。extension: required を持つオブジェクトは、それ自体でユーザーには表示されません。別の LookML オブジェクトによって拡張される出発点としてのみ機能します。extension パラメータは、ExploreビューLookML ダッシュボードでサポートされています。

extension: required を含む explore は、データテストexplore_source として使用できません。LookML Validator は、explore_source が見つからないことを示すエラーを生成します。

メタデータを使用したオブジェクトの拡張機能の表示

Looker IDE で explore パラメータや view パラメータをクリックすると、メタデータ パネルを使ってオブジェクトの拡張機能を確認したり、拡張したオブジェクトを確認したりできます。詳細については、LookML オブジェクトのメタデータのドキュメント ページをご覧ください。

extends の実装の詳細

Looker が LookML オブジェクトを拡張するときに行う手順は、次のとおりです。

  1. 拡張されるオブジェクトをコピーする: 拡張されるビュー、Explore、または LookML ダッシュボードに対して Looker が LookML のコピーを作成します。この新しいコピーは、拡張オブジェクトです。
  2. 2 つのコピーの LookML を結合する: Looker が、拡張されるオブジェクトの LookML を、拡張するオブジェクトに結合します。
  3. コピー間の競合を解決する: ほとんどの部分で、LookML 要素が、拡張されるオブジェクトと拡張するオブジェクトの両方で定義される場合、拡張するオブジェクト内のバージョンが使用されます。ただし、言い換えると、拡張機能は、値をオーバーライドするのではなく、パラメータ値を結合します。詳細については、このページのパラメータの組み合わせのセクションをご覧ください。
  4. LookML を適用する: すべての競合が解決されると、Looker は標準ロジックを使用して生成された LookML を解釈します。言い換えると、Looker は、他のビュー、Explore、LookML ダッシュボードと同様に、標準のデフォルトと前提条件をすべて使用します。

以降のセクションでは、例としてビューを拡張する手順を示します。ベースビューである [User] ビューの LookML を次に示します。

view: user {
  suggestions: yes

  dimension: name {
    sql: ${TABLE}.name ;;

  }
  dimension: status {
    sql: ${TABLE}.status ;;
    type: number
  }
}

次に示すのは、[User] ビューを拡張した [User with Age Extensions] ビューの LookML です。

include: "/views/user.view"

view: user_with_age_extensions {
  extends: [user]
  suggestions: no

  dimension: age {
    type: number
    sql: ${TABLE}.age ;;
  }

  dimension: status {
    type: string
  }
}

ステップ 1: LookML をコピーする

この場合、user ビューは user_with_age_extensions ビューに拡張されます。user は拡張されるビューであるため、結合前にそのコピーが作成されます。コピーが作成されるという事実は、ここでは特に重要ではありません。元の user ビューが変更されず、通常どおり使用できるという事実が重要です。

ステップ 2: コピーを結合する

次のステップは、拡張されるビュー(user)から拡張するビュー(user_with_age_extensions)に結合されるすべての LookML ビューに適用されます。このマージの本質である、LookML オブジェクトの結合は単純であるということを理解することが重要です。具体的には、明示的に作成された LookML は結合されますが、作成していないデフォルトの LookML 値は結合されないことを意味します。ある意味で、これは結合される LookML のテキスト事態であり、そのテキストが意味する内容は関係ありません。

ステップ 3: 競合を解決する

3 番目のステップは、結合されるビュー間の競合を解決することです。

ほとんどの部分で、LookML 要素が拡張されるオブジェクトと拡張するオブジェクトの両方で定義されている場合、拡張するオブジェクトのバージョンが使用されます。ただし、言い換えると、拡張機能は、値をオーバーライドするのではなく、パラメータ値を結合します。詳細については、このページのパラメータの組み合わせのセクションをご覧ください。

user_with_age_extensions の例の場合、どのパラメータも追加されておらず、特別なリスト オプションsql キーワードは指定されていません。そのため、拡張するビューのパラメータ値は拡張されるビューのパラメータ値をオーバーライドします。

  • 拡張するビュー名(user_with_age_extensions)は、拡張されるビュー名(user)をオーバーライドします。
  • suggestions: no の拡張する値は、拡張される suggestions: yes 値をオーバーライドします。
  • 拡張するビューには age というディメンションがあります。これは、拡張されるビューには存在しません(競合なし)。
  • 拡張されるビューは name というディメンションがあります。これは、拡張するビューには存在しません(競合なし)。
  • 拡張するビューの status ディメンションの type: string 値は、拡張されるビューの type: number 値をオーバーライドします。
  • status ディメンションには sql パラメータがあります。これは、拡張するビューには存在しません(競合なし)。

デフォルトの LookML 値がまだ考慮されていないという事実は重要です。デフォルト値間の競合が解決されていると誤解するのを避けたいためです。実際には、このステップでは無視されるだけです。そのため、オブジェクトを拡張するときは、次のようにパラメータを明示的に追加する必要があります。

この例では、sql_table_name を [User] ビューに追加しません。そのため、次のステップで問題が発生します。

ステップ 4: LookML を通常どおり解釈する

最後のステップでは、生成される LookML が、すべてのデフォルト値を含めて通常と解釈されます。この例における結果のビュー LookML は、次のように解釈されます。

include: "/views/user.view"

view: user_with_age_extensions {
  suggestions: no

  dimension: age {
    type: number
    sql: ${TABLE}.age ;;
  }

  dimension: name {
    sql: ${TABLE}.name ;;
  }

  dimension: status {
    sql: ${TABLE}.status ;;
    type: string
  }
}

結果の LookML には view: user_with_age_extensions が含まれますが、sql_table_name パラメータは含まれないことがわかります。その結果、Looker では、sql_table_name の値がビュー名と同じであると想定することになります。

問題は、データベースに user_with_age_extensions というテーブルがないことです。そのため、拡張されるビューに sql_table_name パラメータを追加する必要があります。拡張される Explore に view_nameview_label を追加すると、同様の問題を回避できます。

extends の組み合わせ

拡張で LookML オブジェクトを利用する方法はいくつかあります。

高度なユースケースの例を確認してトラブルシューティングのヒントを読むには、高度な extends ユースケースの例のトラブルシューティングのベスト プラクティスのページをご覧ください。

複数のオブジェクトを同時に拡張する

複数のダッシュボード、ビュー、または Explore を同時に拡張できます。次に例を示します。

explore: orders {
  extends: [user_info, marketing_info]
}
# Also works for dashboards and views

拡張プロセスは、実装例で説明したように動作しますが、競合の解決方法に関する追加ルールが 1 つあります。extends パラメータに表示されている複数の項目間に競合が存在する場合、最後に表示されている項目が優先されます。したがって、上記の例では、user_infomarketing_info の間に競合がある場合、marketing_info Explore が優先します。

複数の拡張機能をチェーンする

また、拡張機能は必要な数だけチェーンできます。次に例を示します。

explore: orders {
  extends: [user_info]
  ...
}
explore: user_info {
  extends: [marketing_info]
  ...
}

拡張プロセスは、実装例で説明したように動作しますが、競合の解決方法に関する追加ルールが 1 つあります。競合が存在する場合、拡張機能のチェーン内の最後の項目が優先されます。この例では、次のようになります。

  • orders は、user_infomarketing_info の両方よりも優先されます。
  • user_infomarketing_info よりも優先されます。

パラメータの組み合わせ

ほとんどの部分で、LookML 要素が拡張されるオブジェクトと拡張するオブジェクトの両方で定義されている場合、拡張するオブジェクトのバージョンが使用されます。このページの実装例では、このケースでした。

ただし、次の場合は、拡張機能は、値をオーバーライドするのではなく、パラメータ値を組み合わせます。

一部のパラメータは追加型

多くの場合、拡張するオブジェクトに拡張されるオブジェクトと同じパラメータが含まれていると、拡張するオブジェクトの値は、拡張されるオブジェクトのパラメータ値をオーバーライドします。ただし、一部のパラメータでは拡張機能を追加型にすることが可能です。つまり、拡張するオブジェクトの値は、拡張されるオブジェクトの値と組み合わせて使用されます。

以下のパラメータは追加型です。

次の例では、carriers ビューに link パラメータを持つ name ディメンションがあります。

view: carriers {
  sql_table_name: flightstats.carriers ;;

  dimension: name {
    sql: ${TABLE}.name ;;
    type: string
    link: {
      label: "Google {{ value }}"
      url: "http://www.google.com/search?q={{ value }}"
      icon_url: "http://google.com/favicon.ico"
    }
  }
}

次に、carriers ビューを拡張した carriers_extended ビューを示します。carriers_extended ビューには、link パラメータに異なる設定を伴う name ディメンションもあります。


include: "/views/carriers.view.lkml"

view: carriers_extended {
  extends: [carriers]

  dimension: name {
    sql: ${TABLE}.name ;;
    type: string
    link: {
      label: "Dashboard for {{ value }}"
      url: "https://docsexamples.dev.looker.com/dashboards/307?Carrier={{ value }}"
      icon_url: "https://www.looker.com/favicon.ico"
    }
  }
}

carriers_extended ビューでは、2 つの link パラメータが追加型であるため、name ディメンションにより両方のリンクが表示されます。

リストの追加オプション

リストを操作する際は、拡張するオブジェクトのリストを優先する代わりに、それらを組み合わせることもできます。たとえば、animals という競合するリストを持つ次の単純な拡張機能があるとします。

view: pets {
  extends: fish
  set: animals {
    fields: [dog, cat]
  }
}
view: fish {
  set: animals {
    fields: [goldfish, guppy]
  }
}

この例では、pets ビューは拡張を行っているため、animals の作成に [dog, cat] が含まれます。ただし、特別な EXTENDED* セットを使用すると、代わりにリストを組み合わせることができます。

view: pets {
  extends: fish
  set: animals {
    fields: [dog, cat, EXTENDED*]
  }
}
view: fish {
  set: animals {
    fields: [goldfish, guppy]
  }
}

これで、animals リストに [dog, cat, goldfish, guppy] が含まれるようになりました。

競合解決中に置換せずに組み合わせる

ほとんどの場合、拡張中に競合が発生すると、拡張するオブジェクトが優先されます。たとえば、次の単純な拡張機能があるとします。

view: product_short_descriptions {
  extends: products
  dimension: description {
    sql: ${TABLE}.short_description ;;
  }
}
view: products {
  dimension: description {
    sql: ${TABLE}.full_description ;;
  }
}

description ディメンション内に sql パラメータの競合があることがわかります。通常、product_short_descriptions の定義では、拡張を行うため、products の定義を単純に上書きします。

ただし、必要に応じて定義を組み合わせることもできます。そのためには、次のように ${EXTENDED} キーワードを使用します。

view: product_short_descriptions {
  extends: products
  dimension: description {
    sql: LEFT(${EXTENDED}, 50) ;;
  }
}
view: products {
  dimension: description {
    sql: ${TABLE}.full_description ;;
  }
}

ここで、sql パラメータの競合に関する対処が異なります。product_short_descriptions 定義を優先する代わりに、products から定義を取得し、${EXTENDED} が使用される場所に挿入します。この場合の description の定義は、LEFT(${TABLE}.full_description, 50) になります。

注意点

ローカライズのあるプロジェクト

オブジェクトを拡張する場合は、拡張機能にもローカライズ ルールが適用されることに注意してください。オブジェクトを拡張して新しいラベルや説明を定義する場合は、プロジェクトのロケール文字列ファイルにローカライズ定義を指定する必要があります。詳細については、LookML モデルのローカライズのドキュメント ページをご覧ください。