使用 extends 重複使用程式碼

這是進階主題,假設讀者對 LookML 有紮實的知識。

總覽

隨著 LookML 模型的大小和複雜度增加,在多個位置重複使用 LookML 的用途也越來越廣泛。extends 參數可讓您重複使用程式碼,協助您執行下列操作:

  • 編寫 DRY (don't repeat yourself) 程式碼,以便在單一位置定義項目,讓程式碼更一致且更快編輯
  • 為不同使用者管理不同的欄位組合
  • 在專案的不同部分共用設計模式
  • 在專案中重複使用彙整、維度或評量組合

如要擴充 LookML 物件,請建立新的 LookML 物件,然後加入 extends 參數,指出新物件是現有物件的擴充功能。也就是說,您的專案會有兩個版本的 LookML 物件。如果發生任何衝突,擴充物件會優先採用,並覆寫要擴充物件的設定。詳情請參閱本頁下方的「extends 的實作詳細資料」一節。

查看 LookML 精修:如果您想建立多個檢視畫面或探索,建議您擴充檢視畫面或探索。不過,如果您只想修改檢視表或「探索」,而不想編輯包含這些項目的 LookML 檔案,建議改用精進功能。您也可以在精修項目中使用 extends 參數。如需更多資訊和使用案例,請參閱 LookML 精修功能說明文件頁面。

您可以擴充檢視畫面、探索和 LookML 資訊主頁:

模型無法擴充,且您無法在其他模型檔案中加入模型檔案。相反地,如果您想在多個模型中重複使用或擴充「探索」,可以建立個別的「探索」檔案,然後在模型檔案中加入該「探索」檔案

請參閱以下擴充「探索」擴充 LookML 資訊主頁的範例。

擴充探索

以下是擴充探索的範例:

explore: customer {
  persist_for: "12 hours"
}

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

在這個範例中,我們有一個名為「Customer」的探索,並建立了第二個名為「Transaction」的探索來擴充前者。Customer 中的所有內容 (例如彙整) 都會納入 TransactionTransaction 中的所有內容都會保留在 Transaction 中。

但請注意,這兩者之間存在衝突:客戶探索指出 persist_for 應設為 12 小時,但交易探索則指出應設為 5 分鐘。對於「交易」探索,系統會使用 persist_for: "5 minutes" 設定,因為它會覆寫所擴充探索的設定。

擴充 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 資訊主頁,因此 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

由於這些元素位於不同的資訊主頁檔案中,因此很容易遺漏。因此,如果要將資訊方塊新增至延伸資訊主頁,請務必檢查延伸資訊主頁中的資訊方塊與延伸資訊主頁中的資訊方塊之間是否有位置衝突。

要求擴充功能

您可以使用 extension: required 參數,將 LookML 物件標示為需要擴充資料,也就是說物件無法單獨使用。含有 extension: required 的物件本身並不會向使用者顯示,而是用於做為其他 LookML 物件擴充的起點。extension 參數適用於探索檢視畫面LookML 資訊主頁

含有 extension: requiredexplore 無法用於資料測試explore_sourceLookML 驗證工具會產生錯誤,指出找不到 explore_source

使用中繼資料查看物件的擴充資料

您可以點選 Looker IDE 中的 exploreview 參數,並使用中繼資料面板查看物件的任何擴充功能,或查看該擴充功能擴充了哪些物件。詳情請參閱「LookML 物件中繼資料」說明文件頁面。

extends 的實作詳細資料

以下是 Looker 擴充 LookML 物件時採取的步驟:

  1. 複製要擴充的物件:Looker 會為要擴充的檢視畫面、探索或 LookML 資訊主頁建立 LookML 副本。這個新副本就是擴充物件。
  2. 合併兩個副本的 LookML:Looker 會將擴展物件的 LookML 合併至擴展物件。
  3. 解決副本之間的衝突:在大多數情況下,如果在擴充物件和擴充物件中都定義了 LookML 元素,系統會使用擴充物件中的版本。不過,在其他情況下,擴充功能會合併參數值,而非覆寫值。請參閱本頁的「合併參數」一節。
  4. 套用 LookML:解決所有衝突後,Looker 會使用標準邏輯解讀產生的 LookML。換句話說,Looker 會使用所有標準預設值和假設,就像任何其他檢視表、探索或 LookML 資訊主頁一樣。

以下各節將說明這些步驟的具體內容,並以擴充檢視畫面為例。以下是基本檢視畫面 (User 檢視畫面) 的 LookML:

view: user {
  suggestions: yes

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

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

以下是 User with Age Extensions 檢視畫面的 LookML,可擴充 User 檢視畫面:

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) 中的所有 LookML 合併到擴充檢視畫面 (user_with_age_extensions)。請務必瞭解這項合併作業的性質,也就是 LookML 物件的合併作業。實際上,這表示所有明確寫入的 LookML 都會合併,但您未寫入的預設 LookML 值不會合併。從某種意義來說,這只是將 LookML 的文字組合在一起,而沒有任何文字意義。

步驟 3:解決衝突

第三步驟是解決合併檢視畫面之間的任何衝突。

在大多數情況下,如果在擴充物件和擴充物件中都定義了 LookML 元素,系統會使用擴充物件中的版本。不過,在其他情況下,擴充功能會合併參數值,而非覆寫值。請參閱本頁的「合併參數」一節。

user_with_age_extensions 範例中,沒有任何參數是加法,也沒有指定特殊的清單選項sql 關鍵字,因此擴充檢視畫面中的參數值會覆寫擴充檢視畫面中的參數值:

  • 延伸檢視畫面名稱 (user_with_age_extensions) 會覆寫延伸檢視畫面名稱 (user)。
  • suggestions: no 的 extending 值會覆寫 extendedsuggestions: 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 參數。如要避免類似問題,請在要擴充的探索中加入 view_nameview_label

結合擴充

您可以透過下列幾種方式,利用擴充功能來運用 LookML 物件:

如要查看進階用途範例和疑難排解訣竅,請參閱「進階 extends 用途範例的疑難排解最佳做法」一文。

同時延伸多個物件

您可以同時擴展多個資訊主頁、檢視畫面或探索。例如:

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

擴充程序的運作方式與實作範例完全相同,但有一個額外的規則,說明如何解決衝突。如果 extends 參數中列出的多個項目之間發生衝突,系統會優先採用最後列出的項目。因此,在上述範例中,如果 user_infomarketing_info 之間發生衝突,系統會優先採用 marketing_info 探索。

將多個擴充項目鏈結在一起

您也可以將多個擴充項目鏈結在一起,數量不限。例如:

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

同樣地,擴充程序的運作方式與實作範例中所述完全相同,但有一個額外的衝突解決規則。如果發生任何衝突,系統會優先套用擴充鏈結中的最後一個項目。在這個例子中:

  • orders 的優先順序高於 user_infomarketing_info
  • user_info 優先於 marketing_info

結合參數

在大多數情況下,如果在擴充物件和擴充物件中都定義了 LookML 元素,系統會使用擴充物件中的版本。本頁的實作範例就是這種情況。

不過,在下列情況下,擴充功能會合併參數值,而非覆寫值:

部分參數可加總

在許多情況下,如果擴充物件包含與要擴充物件的參數相同,則擴充物件的值會覆寫擴充物件的參數值。不過,部分參數的擴充資料可做為加法運算,也就是說,擴充物件中的值會與擴充物件中的值一併使用。

下列參數為加總

在以下範例中,carriers 檢視畫面含有 name 維度,其中包含 link 參數:

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_extended 檢視畫面,可擴充 carriers 檢視畫面。carriers_extended 檢視畫面也包含 name 維度,在 link 參數中設定不同的設定:


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 檢視畫面中,兩個 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 模型本地化」說明文件。