שימוש חוזר בקוד באמצעות extends

זהו נושא מתקדם שמיועד לקוראים עם ידע מעמיק ב-LookML.

סקירה כללית

ככל שמודל LookML גדל ומורכב יותר, כך נעשה שימוש חוזר ב-LookML במקומות רבים יותר. הפרמטר extends מאפשר לכם לעשות שימוש חוזר בקוד, וכך:

  • כדאי לכתוב קוד DRY (אל תחזרו על עצמכם), כדי שתוכלו להגדיר דברים במקום אחד בלבד, וכך הקוד יהיה עקבי יותר וקל יותר לעריכה
  • ניהול של קבוצות שדות שונות למשתמשים שונים
  • שיתוף דפוסי עיצוב בחלקים שונים של הפרויקט
  • שימוש חוזר בקבוצות של צירופים, מאפיינים או מדדים בפרויקט

כדי להרחיב אובייקט של LookML, יוצרים אובייקט של LookML חדש ואז מוסיפים את הפרמטר extends כדי לציין שהאובייקט החדש הוא הרחבה של אובייקט קיים. כלומר, בפרויקט יהיו שתי גרסאות של אובייקט LookML. אם יש התנגשויות, האובייקט המורחב יקבל עדיפות ויבטל את ההגדרות של האובייקט שמורחב. פרטים נוספים מופיעים בהמשך הדף בקטע פרטי ההטמעה של extends.

כדאי לעיין בשיפורים של LookML: הרחבה של תצוגה או של Explore מתאימה לתרחישים שבהם רוצים ליצור כמה גרסאות של התצוגה או של Explore. אבל אם המטרה שלכם היא פשוט לשנות תצוגה או ניתוח ב-Explore בלי לערוך את קובץ ה-LookML שמכיל אותם, כדאי להשתמש במקום זאת בשיפור. אפשר גם להשתמש בפרמטר extends בתוך מסנן. מידע נוסף ותרחישי שימוש מופיעים בדף התיעוד בנושא שיפורים ב-LookML.

אפשר להרחיב תצוגות, ניתוחים ולוחות בקרה של LookML:

אי אפשר להרחיב מודלים, ואי אפשר לכלול קובץ מודל בקובץ מודל אחר. במקום זאת, אם רוצים לעשות שימוש חוזר ב-Explores או להרחיב אותם במודלים שונים, אפשר ליצור קובץ Explore נפרד ואז לכלול את קובץ ה-Explore הזה בקובץ מודל.

בדוגמאות הבאות מוסבר איך להרחיב ניתוח ב-Explore ואיך להרחיב מרכז שליטה של LookML.

הרחבת ניתוח

לדוגמה, כך מרחיבים ניתוח:

explore: customer {
  persist_for: "12 hours"
}

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

בדוגמה הזו יש לנו ניתוח שנקרא Customer, ויצרנו ניתוח שני שנקרא Transaction שהוא הרחבה של הניתוח הראשון. כל מה שנמצא בטבלה Customer, כמו הצטרפויות, ייכלל בטבלה Transaction. כל מה שמופיע בעסקאות יישאר בעסקאות.

אבל שימו לב שיש סתירה: בדוח 'ניתוח נתונים' של הלקוח מצוין שההגדרה persist_for צריכה להיות 12 שעות, אבל בדוח 'ניתוח נתונים' של העסקה מצוין שהיא צריכה להיות 5 דקות. בדוח העסקאות ב-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.lookml ו-faa_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.

אי אפשר להשתמש בexplore עם extension: required כexplore_source עבור בדיקת נתונים. כלי התיקוף של LookML יציג שגיאה שבה מצוין שלא ניתן למצוא את explore_source.

שימוש במטא-נתונים כדי לראות הרחבות של אובייקט

אפשר ללחוץ על פרמטר explore או view ב-Looker IDE ולהשתמש בחלונית המטא-נתונים כדי לראות אילו תוספים יש לאובייקט, או כדי לראות איזה אובייקט הוא מרחיב. מידע נוסף זמין בדף התיעוד בנושא מטא-נתונים של אובייקטים ב-LookML.

פרטי ההטמעה של extends

אלה השלבים שמערכת Looker מבצעת כשמרחיבים אובייקט של LookML:

  1. העתקת האובייקט שמרחיבים: ‏ Looker יוצר עותק של קוד ה-LookML של התצוגה, של ה-Explore או של מרכז השליטה של LookML שמרחיבים. העותק החדש הוא אובייקט מורחב.
  2. מיזוג ה-LookML של שני העותקים: ‏ Looker ממזג את ה-LookML של האובייקט שמורחב עם האובייקט שמרחיב.
  3. פתרון קונפליקטים בין העותקים: ברוב המקרים, אם רכיב LookML מוגדר גם באובייקט המקורי וגם באובייקט המורחב, נעשה שימוש בגרסה שבאובייקט המורחב. עם זאת, במקרים אחרים, התוספים ישלבו את ערכי הפרמטרים במקום להחליף את הערכים. מידע נוסף מופיע בקטע שילוב פרמטרים בדף הזה.
  4. החלת ה-LookML: אחרי שכל הקונפליקטים נפתרים, מערכת Looker מפרשת את ה-LookML שנוצר באמצעות הלוגיקה הרגילה. במילים אחרות, Looker ישתמש בכל ברירות המחדל וההנחות הרגילות כמו בכל תצוגה, Explore או מרכז שליטה של LookML.

בקטעים הבאים מפורטים השלבים האלה, עם דוגמה להרחבת תצוגה. זהו קוד ה-LookML של תצוגת הבסיס שלנו, התצוגה User:

view: user {
  suggestions: yes

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

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

הנה קוד ה-LookML של התצוגה User with Age Extensions, שהיא הרחבה של התצוגה 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: מיזוג העותקים

בשלב הבא, כל קוד ה-LookML מתצוגת הבסיס (user) ימוזג עם תצוגת ההרחבה (user_with_age_extensions). חשוב להבין את אופי המיזוג הזה, שהוא פשוט מיזוג של אובייקטים של LookML. בפועל, המשמעות היא שכל קוד LookML שנכתב במפורש ימוזג, אבל ערכי ברירת המחדל של LookML שלא כתבתם לא ימוזגו. במובן מסוים, מדובר רק בטקסט של LookML שנוצר, ולא במשמעות של הטקסט הזה.

שלב 3: פתרון בעיות של התנגשויות

השלב השלישי הוא לפתור את כל ההתנגשויות בין התצוגות הממוזגות.

ברוב המקרים, אם רכיב LookML מוגדר גם באובייקט המורחב וגם באובייקט המרחיב, נעשה שימוש בגרסה שבאובייקט המרחיב. עם זאת, במקרים אחרים, התוספים ישלבו את ערכי הפרמטרים במקום להחליף את הערכים. מידע נוסף מופיע בקטע שילוב פרמטרים בדף הזה.

בדוגמה user_with_age_extensions, אף אחד מהפרמטרים לא מצטבר, ולא צוינו אפשרויות מיוחדות לרשימה או מילות מפתח של sql, ולכן ערכי הפרמטרים בתצוגה המורחבת יחליפו את ערכי הפרמטרים בתצוגה המורחבת:

  • שם התצוגה המרחיבה (התרחבות) (user_with_age_extensions) גובר על שם התצוגה המורחבת (התרחבות) (user).
  • הערך suggestions: no של המאפיין מאריך מבטל את הערך suggestions: yes של המאפיין מאורך.
  • לתצוגה המורחבת יש מאפיין שנקרא age, שלא קיים בתצוגה המרחיבה (אין התנגשות).
  • בתצוגה המפורטת מורחבת יש מאפיין שנקרא name, שלא קיים בתצוגה המפורטת מרחיבה (אין התנגשות).
  • הערך type: string של המאפיין status בתצוגה המורחבת מחליף את הערך 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_name ואת view_label לחיפושים שיוגדלו.

שילוב של תגי extends

יש כמה דרכים להשתמש באובייקטים של LookML עם extends:

כדי לראות דוגמה לתרחיש שימוש מתקדם ולקרוא טיפים לפתרון בעיות, אפשר לעיין בדף השיטות המומלצות בנושא פתרון בעיות בדוגמה לתרחיש שימוש מתקדם ב-extends.

הארכת יותר מאובייקט אחד בו-זמנית

אפשר להרחיב יותר מלוח בקרה אחד, תצוגה אחת או דוח אחד ב-Explore בו-זמנית. לדוגמה:

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

תהליך ההרחבה פועל בדיוק כמו שמתואר בדוגמה להטמעה, אבל יש כלל נוסף לגבי אופן פתרון ההתנגשויות. אם יש סתירות בין כמה פריטים שמופיעים בפרמטר extends, המערכת תיתן עדיפות לפריטים שמופיעים אחרונים. לכן, בדוגמה הקודמת, אם היו סתירות בין user_info לבין marketing_info, הניתוח ב-marketing_info היה גובר.

שרשור של כמה תגי extend

אפשר גם לשרשר כמה פקודות extend שרוצים. לדוגמה:

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

שוב, תהליך ההרחבה פועל בדיוק כמו שמתואר בדוגמה להטמעה, עם כלל נוסף לגבי פתרון קונפליקטים. אם יש סתירות, העדיפות ניתנת לפריט האחרון בשרשרת ההרחבות. בדוגמה הזו:

  • ל-orders תהיה עדיפות על פני user_info ו-marketing_info.
  • user_info תקבל עדיפות על פני marketing_info.

שילוב פרמטרים

ברוב המקרים, אם רכיב LookML מוגדר גם באובייקט extended וגם באובייקט extending, נעשה שימוש בגרסה שבאובייקט extending. כך קורה בדוגמה להטמעה בדף הזה.

עם זאת, במקרים הבאים, התוספים ישלבו את ערכי הפרמטרים במקום להחליף את הערכים:

חלק מהפרמטרים הם מצטברים

במקרים רבים, אם האובייקט המרחיב מכיל את אותו פרמטר כמו האובייקט המורחב, הערכים של האובייקט המרחיב יחליפו את ערכי הפרמטר של האובייקט המורחב. אבל התוספים יכולים להיות מצטברים עבור חלק מהפרמטרים, כלומר הערכים מהאובייקט המרחיב משמשים בשילוב עם הערכים מהאובייקט המורחב.

הפרמטרים הבאים הם תוספתיים:

בדוגמה הבאה, לתצוגה המפורטת 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 ;;
  }
}

אפשר לראות שיש התנגשות של הפרמטר sql במאפיין description. בדרך כלל, ההגדרה מ-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.