לפני שמתחילים
נכנסים לדף Dataform במסוף Google Cloud .
בוחרים מאגר או יוצרים מאגר.
בוחרים או יוצרים סביבת עבודה לפיתוח.
התפקידים הנדרשים
כדי לקבל את ההרשאות שדרושות ליצירת טענות נכוֹנוּת (assertion) ובדיקות יחידה (unit testing), צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים:
- Dataform Editor (
roles/dataform.editor) בסביבת העבודה -
כדי לסנכרן את המטא-נתונים של ההצהרה עם Knowledge Catalog:
Dataplex Catalog Editor (
roles/dataplex.catalogEditor) בפרויקט או בקבוצת הרשומות@bigquery
להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.
יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.
בדיקת נתונים באמצעות הצהרות
טענה היא שאילתת בדיקה של איכות הנתונים שמאתרת שורות שמפירות תנאי אחד או יותר שצוינו בשאילתה. אם השאילתה מחזירה שורות כלשהן, הטענה נכשלת. Dataform מריץ הצהרות בכל פעם שהוא מעדכן את תהליך העבודה, והוא מתריע אם הצהרה כלשהי נכשלת.
Dataform יוצר באופן אוטומטי תצוגות ב-BigQuery שמכילות את התוצאות של שאילתות טענות שעברו קומפילציה. כפי שהוגדר בקובץ הגדרות תהליך העבודה, Dataform יוצר את התצוגות האלה בסכימת טענות, שבה אפשר לבדוק את תוצאות הטענות.
לדוגמה, עבור סכימת ברירת המחדל dataform_assertions, Dataform יוצר תצוגה ב-BigQuery בפורמט הבא:
dataform_assertions.assertion_name.
אפשר ליצור הצהרות לכל סוגי הטבלאות ב-Dataform: טבלאות, טבלאות מצטברות, תצוגות (views) ותצוגות חומריות (materialized views).
אפשר ליצור הצהרות בדרכים הבאות:
איך מוסיפים הצהרות מובנות לבלוק ההגדרות של טבלה
אפשר להוסיף הצהרות מובנות לבלוק
configשל טבלה ולציין את התנאים שלהן.הוספת הצהרות ידניות בקובץ SQLX נפרד.
אתם יכולים לכתוב טענות מותאמות אישית באופן ידני בקובץ SQLX נפרד לתרחישי שימוש מתקדמים או למערכי נתונים שלא נוצרו על ידי Dataform.
יצירת טענות מובנות
אפשר להוסיף הצהרות מובנות של Dataform לבלוק config של טבלה. Dataform מריץ את ההצהרות האלה אחרי יצירת הטבלה. אחרי ש-Dataform יוצר את הטבלה, אפשר לראות אם האימות עבר בהצלחה בכרטיסייה Workflow execution logs (יומני ביצוע של תהליך העבודה) בסביבת העבודה.
אפשר ליצור את הטענות הבאות בבלוק config של טבלה:
nonNullהתנאי הזה קובע שהעמודות שצוינו לא יכולות להיות ריקות בכל השורות בטבלה. התנאי הזה משמש לעמודות שלעולם לא יכולות להיות null.
בדוגמת הקוד הבאה מוצגת טענת
nonNullבבלוקconfigשל טבלה:
config {
type: "table",
assertions: {
nonNull: ["user_id", "customer_id", "email"]
}
}
SELECT ...
rowConditionsהתנאי הזה קובע שכל השורות בטבלה פועלות לפי הלוגיקה המותאמת אישית שהגדרתם. כל תנאי שורה הוא ביטוי SQL מותאם אישית, וכל שורה בטבלה מוערכת לפי כל תנאי שורה. הטענה נכשלת אם שורה כלשהי בטבלה מחזירה את הערך
false.בדוגמת קוד הבאה מוצגת טענת נכוֹנוּת (assertion)
rowConditionsבהתאמה אישית בבלוקconfigשל טבלה מצטברת:
config {
type: "incremental",
assertions: {
rowConditions: [
'signup_date is null or signup_date > "2022-08-01"',
'email like "%@%.%"'
]
}
}
SELECT ...
uniqueKeyהתנאי הזה קובע שבעמודה שצוינה, לאף שורה בטבלה אין את אותו הערך.
בדוגמה הבאה של קוד אפשר לראות טענת
uniqueKeyבבלוקconfigשל תצוגה:
config {
type: "view",
assertions: {
uniqueKey: ["user_id"]
}
}
SELECT ...
uniqueKeysהתנאי הזה קובע שבשום שורה בטבלה לא מופיע אותו ערך בעמודות שצוינו. האימות נכשל אם יש יותר משורה אחת בטבלה עם אותם ערכים בכל העמודות שצוינו.
בדוגמת הקוד הבאה מוצגת טענת
uniqueKeysבבלוקconfigשל טבלה:
config {
type: "table",
assertions: {
uniqueKeys: [["user_id"], ["signup_date", "customer_id"]]
}
}
SELECT ...
הוספת טענות נכוֹנוּת (assertions) לבלוק config
כדי להוסיף הצהרות לבלוק ההגדרות של טבלה, פועלים לפי השלבים הבאים:
- בסביבת העבודה לפיתוח, בחלונית Files (קבצים), בוחרים קובץ SQLX של הגדרת טבלה.
- בבלוק
configשל קובץ הטבלה, מזיניםassertions: {}. - בתוך
assertions: {}, מוסיפים את הטענות. - אופציונלי: לוחצים על עיצוב.
בדוגמת הקוד הבאה אפשר לראות את התנאים שנוספו בבלוק config:
config {
type: "table",
assertions: {
uniqueKey: ["user_id"],
nonNull: ["user_id", "customer_id"],
rowConditions: [
'signup_date is null or signup_date > "2019-01-01"',
'email like "%@%.%"'
]
}
}
SELECT ...
יצירת הצהרות ידניות באמצעות SQLX
טענות ידניות הן שאילתות SQL שכותבים בקובץ SQLX ייעודי. שאילתת SQL של טענת נכונות ידנית צריכה להחזיר אפס שורות. אם השאילתה מחזירה שורות כשהיא מופעלת, הטענה נכשלת.
כדי להוסיף הצהרות ידניות בקובץ SQLX חדש, פועלים לפי השלבים הבאים:
- בחלונית קבצים, לצד
definitions/, לוחצים על סמל האפשרויות הנוספות
. - לוחצים על יצירת קובץ.
בשדה Add a file path (הוספת נתיב קובץ), מזינים את שם הקובץ ואחריו את התו
.sqlx. לדוגמה,definitions/custom_assertion.sqlx.שמות הקבצים יכולים לכלול רק מספרים, אותיות, מקפים וקווים תחתונים.
לוחצים על יצירת קובץ.
בחלונית קבצים, לוחצים על הקובץ החדש.
בקובץ, מזינים את הפרטים הבאים:
config { type: "assertion" }מתחת לבלוק
config, כותבים את שאילתת ה-SQL או כמה שאילתות.אופציונלי: לוחצים על עיצוב.
בדוגמת הקוד הבאה מוצגת טענה ידנית בקובץ SQLX, שקובעת שהשדות A, B ו-c אף פעם לא יהיו NULL ב-sometable:
config { type: "assertion" }
SELECT
*
FROM
${ref("sometable")}
WHERE
a IS NULL
OR b IS NULL
OR c IS NULL
בדיקת איכות הנתונים באמצעות בדיקות יחידה
בדיקת יחידה היא בדיקה של איכות הנתונים, שמוגדרת בקובץ .sqlx ייעודי, שמדמה את כל התלות של פעולת זרימת העבודה שנבדקת ומספקת תוצאות צפויות.
אפשר להשתמש בבדיקות יחידה כדי לבדוק פעולות ב-Dataform מול קלט מדומה מבוקר, כדי לוודא שקוד הפעולה מטפל בצורה נכונה במקרים קיצוניים, בערכי null, בצבירות, בביטויים רגולריים ובלוגיקה מותנית.
הגדרת מוקאפים לתלות בפעולות, כמו טבלאות קודמות, תצוגות או הצהרות גולמיות שמפנות לפונקציה ${ref()}, מתבצעת בבלוקים של input. כל בלוק input מפנה לתלות לפי השם שלה ומכיל שאילתת SQL שמגדירה את השורות המדומות. השאילתה הזו היא בדרך כלל סדרה של הצהרות SELECT בשילוב עם UNION ALL.
התוצאות הצפויות הן שאילתות SQL שמייצגות את התוצאות של הרצת הקלט שצוין על הצהרת ה-SQL של פעולת תהליך העבודה.
ב-Dataform, בדיקות היחידה מופעלות שורה אחר שורה, והתוצאה בפועל של הפעלת לוגיקת ה-SQL של פעולת זרימת עבודה מול נתוני דמה מושווית לקבוצת תוצאות צפויה.
בדיקות יחידה יכולות להיות באחד מהמצבים הבאים:
-
SUCCESS: הבדיקה עברה. התוצאות בפועל תואמות לתוצאות הצפויות. FAILURE: הבדיקה נכשלה. התוצאות בפועל לא תואמות לתוצאות הצפויות.
מגבלות
בדיקות יחידה ב-Dataform זמינות עם המגבלות הבאות:
- ב-Dataform core בגרסה
3.0.56ואילך יש בדיקות יחידה. - הגודל המקסימלי של נתוני הקלט בבדיקת יחידה הוא 100 שורות לכל קלט.
יצירת בדיקות יחידה
מאחסנים קובצי .sqlx לבדיקות יחידה בספרייה definitions/.
כדי ליצור קובץ חדש של בדיקת יחידה .sqlx בספרייה definitions/, פועלים לפי השלבים הבאים:
נכנסים לדף Dataform במסוף Google Cloud .
בוחרים מאגר.
בוחרים סביבת עבודה לפיתוח.
בחלונית קבצים, לצד
definitions/, לוחצים על תפריט האפשרויות הנוספות.לוחצים על יצירת קובץ.
בחלונית Create new file:
בשדה הוספת נתיב קובץ, אחרי
definitions/, מזינים את שם הקובץ ואחריו_test.sqlx. לדוגמה,definitions/customer_spend_test.sqlx.שמות הקבצים יכולים לכלול רק מספרים, אותיות, מקפים וקווים תחתונים.
לוחצים על יצירת קובץ.
בקובץ הבדיקה, מוסיפים את הבלוק
configהבא:config { type: "test", dataset: "ACTION_NAME" }מחליפים את ACTION_NAME בשם הפעולה שהבדיקה הזו מאמתת.
כדי ליצור מוקאפ של הפעולה שנבדקת, מוסיפים בלוק
inputלכל תלות בפעולה, וכותבים שאילתת SQL לבדיקת התלות הזו בפורמט הבא:input "DEPENDENCY_NAME" { SELECT ... SELECT ... }מחליפים את DEPENDENCY_NAME בשם של התלות בפעולה שנבדקה, שהקלט הזה מדמה.
מתחת לבלוקים
input, כותבים שאילתות SQL סטנדרטיות שמייצגות את שורות הפלט הצפויות בפורמט הבא:-- Expected Output SELECT ... SELECT ...
השאילתות של הפלט הצפוי צריכות להחזיר רק את השורות והעמודות שהפעולה שנבדקת אמורה להפיק בהינתן קלט מדומה.
בדוגמת הקוד הבאה מוצגת פעולת זרימת העבודה customer_spend.sqlx:
config {
type: "table",
name: "customer_spend"
}
SELECT
c.customer_id,
c.name,
SUM(o.amount) AS total_completed_amount
FROM
${ref("source_customers")} c
JOIN
${ref("source_orders")} o
ON c.customer_id = o.customer_id
WHERE
o.status = 'COMPLETED'
GROUP BY
1, 2
בדוגמת הקוד הבאה מוצגת בדיקת יחידה customer_spend_test.sqlx שמבצעת מוקינג לתלות של פעולת customer_spend.sqlx, ומגדירה תוצאות צפויות למוקים:
config {
type: "test",
dataset: "customer_spend"
}
input "source_customers" {
SELECT 101 AS customer_id, 'Alice' AS name UNION ALL
SELECT 102 AS customer_id, 'Bob' AS name UNION ALL
SELECT 103 AS customer_id, 'Charlie' AS name
}
input "source_orders" {
-- Alice has one completed and one pending order
SELECT 1 AS order_id, 101 AS customer_id, 'COMPLETED' AS status, 100.0 AS amount UNION ALL
SELECT 2 AS order_id, 101 AS customer_id, 'PENDING' AS status, 50.0 AS amount UNION ALL
-- Bob has one completed order
SELECT 3 AS order_id, 102 AS customer_id, 'COMPLETED' AS status, 250.0 AS amount UNION ALL
-- Charlie has no orders
SELECT 4 AS order_id, 999 AS customer_id, 'COMPLETED' AS status, 10.0 AS amount
}
-- Expected Output
SELECT 101 AS customer_id, 'Alice' AS name, 100.0 AS total_completed_amount UNION ALL
SELECT 102 AS customer_id, 'Bob' AS name, 250.0 AS total_completed_amount
הרצת בדיקות יחידה
כדי להריץ בדיקות יחידה, פועלים לפי השלבים הבאים:
המסוף
נכנסים לדף Dataform במסוף Google Cloud .
בוחרים מאגר.
בוחרים סביבת עבודה לפיתוח.
לוחצים על התחלת ההפעלה > ביצוע פעולות.
בחלונית Execute, בקטע Execution mode, בוחרים באפשרות Unit tests.
בוחרים באחת מהאפשרויות הבאות:
- בחירת בדיקות יחידה: מריץ בדיקות יחידה שאתם בוחרים באופן ידני.
- בחירת בדיקות יחידה עם תגים: מריץ בדיקות יחידה עם תג נבחר.
- All unit tests (כל בדיקות היחידה): מריץ את כל בדיקות היחידה בסביבת העבודה.
אופציונלי: בקטע Execution options, מסמנים את התיבה Execute as interactive job with high priority כדי להריץ בדיקות יחידה באופן מיידי, עם עדיפות למהירות הביצוע.
אם לא מסמנים את תיבת הסימון Execute as interactive job with high priority (הפעלה כמשימה אינטראקקטיבית עם עדיפות גבוהה), Dataform מפעיל בדיקות יחידה באמצעות משאבי אצווה כברירת מחדל, ונותן עדיפות לחיסכון בעלויות מחשוב.
לוחצים על התחלת ההפעלה.
API
כדי להריץ בדיקות יחידה באופן פרוגרמטי, יוצרים הפעלה של זרימת עבודה באמצעות השיטה WorkflowInvocations.create, ומגדירים את פרמטרים ההרצה של בדיקות היחידה באובייקט invocationConfig:
"executionMode": "UNIT_TESTS_ONLY"- הפרמטר הזה, שמוגדר לערך
"UNIT_TESTS_ONLY", מפעיל את ההרצה של בדיקות היחידה שמוגדרות במאגר. "queryPriority": "INTERACTIVE"(אופציונלי)- כשהפרמטר הזה מוגדר לערך
"INTERACTIVE", Dataform מריץ שאילתות באופן מיידי. אם לא מוגדרת עדיפות, Dataform מריץ בדיקות יחידה עם עדיפות ברירת המחדל של שאילתת אצווה. "includedTargets": [](אופציונלי)- הפרמטר הזה מאפשר לציין בדיקות יחידה כדי שמערכת Dataform תריץ רק את הבדיקות האלה.
"includedTags": [](אופציונלי)- הפרמטר הזה מאפשר לציין תגים כדי שמערכת Dataform תריץ רק את בדיקות היחידה שתויגו בתגים האלה.
בדוגמת הקוד הבאה מוצג גוף של הפעלת תהליך עבודה שמריץ את כל בדיקות היחידה שמוגדרות במאגר my-repo עם העדיפות שמוגדרת כברירת מחדל לשאילתת אצווה:
{
"compilationResult": "projects/my-project/locations/us/repositories/my-repo/compilationResults/my-compilation-id",
"invocationConfig": {
"executionMode": "UNIT_TESTS_ONLY"
}
}
בדוגמת הקוד הבאה מוצג גוף של הפעלת תהליך עבודה שמריץ רק את בדיקת היחידה my-test עם עדיפות של שאילתה אינטראקטיבית:
{
"compilationResult": "projects/my-project/locations/us/repositories/my-repo/compilationResults/my-compilation-id",
"invocationConfig": {
"executionMode": "UNIT_TESTS_ONLY",
"queryPriority": "INTERACTIVE",
"includedTargets": [
{
"database": "my-project",
"schema": "my-dataset",
"name": "my-test"
}
]
}
}
בדוגמת הקוד הבאה מוצג גוף של הפעלת תהליך עבודה שמריץ בדיקות יחידה במאגר my-repo שתויגו בתווית test-tag-1 או test-tag-2:
{
"compilationResult": "projects/my-project/locations/us/repositories/my-repo/compilationResults/my-compilation-id",
"invocationConfig": {
"executionMode": "UNIT_TESTS_ONLY",
"queryPriority": "INTERACTIVE",
"includedTags": [
"test-tag-1",
"test-tag-2"
]
}
}
בדיקת תוצאות של בדיקות יחידה
אפשר לבדוק את ההבדלים בין הסקריפטים הצפויים והסקריפטים בפועל של בדיקת יחידה בתרשים המהדר או בהפעלות.
תרשים מסוכם
כדי לראות את התסריטים בפועל ואת התסריטים הצפויים של בדיקת יחידה בתרשים המהודר של פעולות בתהליך העבודה, פועלים לפי השלבים הבאים:
נכנסים לדף Dataform במסוף Google Cloud .
בוחרים מאגר.
בוחרים סביבת עבודה לפיתוח.
אופציונלי: כדי לראות את בדיקות היחידה שמקושרות לפעולות שהן בודקות, במקום לראות אותן כצמתים עצמאיים בתרשים, מגדירים את ההגדרה
includeTestsInCompiledGraphל-trueבקובץworkflow_settings.yaml:- בוחרים את הקובץ
workflow_settings.yaml. - מוסיפים את הקוד הבא:
includeTestsInCompiledGraph: true- בוחרים את הקובץ
לוחצים על גרף משולב.
בתרשים המורכב, בוחרים בדיקת יחידה ולוחצים על שאילתה.
משווים בין Actual SQL Script (סקריפט ה-SQL בפועל) לבין Expected SQL Script (סקריפט ה-SQL הצפוי).
הפעלות
נכנסים לדף Dataform במסוף Google Cloud .
בוחרים מאגר.
בוחרים סביבת עבודה לפיתוח.
לוחצים על Executions (הרצות) ואז על View details (הצגת פרטים) ליד בדיקת היחידה שנבחרה.
משווים בין השאילתה של התוצאות בפועל לבין השאילתה של התוצאות הצפויות.
שיטות מומלצות לבדיקות יחידה
- שמירה על גודל קטן של מערכי נתונים לדוגמה
- כדי להאיץ את ההידור ולפשט את ניפוי הבאגים, כדאי להגביל את נתוני הקלט המדומים ל-10 שורות.
- ציון סדר שורות מפורש
- כדי להבטיח סדר שורות דטרמיניסטי במהלך ההערכה, תמיד מוסיפים פסקה של
ORDER BYלשאילתת הפעולה ולשאילתת הפלט הצפוי. - המרת עמודות באופן מפורש בהצהרות המדומות
- המרת סוגי עמודות באופן מפורש בהצהרות המדומות – לדוגמה, באמצעות
CAST(100 AS INT64)– שומרת על הקפדה על סוגים ומונעת שגיאות קומפילציה. - הכללה של תרחישי בדיקה עם
NULLאו ערכים חסרים - הכללת תרחישי בדיקה עם
NULLאו ערכים חסרים בשאילתות המוקדמות של הקלט מבטיחה שהצהרותCOALESCE, פעולות על מחרוזות וקריטריוני סינון יטפלו בצורה בטוחה בנתוני ייצור לא מלאים או בנתוני ייצור מסוג null.
בדוגמת הקוד הבאה מוצג מקרה בדיקה של NULL:
input "source_customers" {
SELECT 101 AS customer_id, 'Alice' AS name UNION ALL
SELECT 102 AS customer_id, NULL AS name -- Test null handling
}
המאמרים הבאים
- מידע נוסף על סוגי הצהרות זמין במאמר בנושא Dataform API.
- כדי ללמוד איך להגדיר הצהרות באמצעות JavaScript, אפשר לעיין במאמר בנושא יצירת תהליכי עבודה באמצעות JavaScript בלבד.
- במאמר הפעלת תהליכי עבודה באופן ידני מוסבר איך להפעיל תהליכי עבודה באופן ידני.