פתרון שגיאות בסכימה

במאמר הזה מוסבר איך לאבחן ולפתור שגיאות HTTP 400 Bad Request שמתרחשות כשמשנים סכימות של טבלאות ב-BigQuery, או כשמגדירים או טוענים מבני סכימה עם רמות עמוקות של הטמעה. במאמר פתרון בעיות באמצעות סכימת מידע מוסבר איך משתמשים בתצוגות של INFORMATION_SCHEMA כדי לפתור בעיות בביצועים של BigQuery.

פתרון שגיאות של אי-התאמה בסכימה

‫BigQuery מחזיר שגיאת Provided Schema does not match Table (reason: invalid) כשאחת מהפעולות הבאות מספקת סכימה שמתנגשת עם הסכימה הקיימת של טבלת היעד:

  • משימת טעינה
  • משימת שאילתה עם טבלת יעד
  • משימת העתקה
  • הצהרת DDL אחת (ALTER TABLE)
  • עדכון של מטא-נתונים בטבלה (tables.update או tables.patch)

כדי לזהות את הסיבה הספציפית ואת הפתרון, התאימו את הודעת השגיאה לאחד מהתרחישים הבאים.

השדה חסר בסכימה החדשה

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Field FIELD_NAME is missing in new schema

האבחון

אחת מהפעולות הבאות מספקת הגדרת סכימה שמשמיטה עמודה אחת או יותר שכבר קיימות בטבלת היעד:

  • משימת טעינה
  • פעולת כתיבה של DataFrame
  • קריאה ל-API מסוג tables.update או tables.patch

רזולוציה

ב-BigQuery אי אפשר להשמיט עמודות באופן משתמע על ידי השמטה שלהן ממטען ייעודי (payload) של סכימת API או מהגדרות של משימת טעינה. כדי לפתור את השגיאה הזו, מבצעים אחת מהפעולות הבאות:

  • צריך לעדכן את צינור עיבוד הנתונים או את בקשת ה-API כך שהסכימה שסופקה תכלול את כל העמודות הקיימות בטבלת היעד.
  • אם אתם מתכוונים להסיר את העמודה מהטבלה, הריצו הצהרת DDL של DROP COLUMN במקום להשמיט את העמודה מבקשת טעינה או תיקון:

    ALTER TABLE `PROJECT_ID.DATASET.TABLE`
    DROP COLUMN FIELD_NAME;

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫PROJECT_ID: מזהה הפרויקט שמכיל את הטבלה.
    • ‫DATASET: שם מערך הנתונים שמכיל את הטבלה.
    • ‫TABLE: שם הטבלה.
    • ‫FIELD_NAME: שם העמודה שרוצים להסיר.

סוג השדה השתנה

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Field FIELD_NAME has changed type from EXISTING_TYPE to NEW_TYPE

האבחון

הבקשה מנסה לשנות את סוג הנתונים של עמודה קיימת (לדוגמה, מ-STRING ל-INT64) במהלך משימת טעינה או עדכון סכימה.

רזולוציה

כדי לפתור את השגיאה הזו, מבצעים אחת מהפעולות הבאות:

  • אם שינוי הסוג הוא המרה נתמכת של סוג נתונים בעמודה (למשל INT64 ל-NUMERIC, INT64 ל-FLOAT64 או NUMERIC ל-BIGNUMERIC), משתמשים בהצהרת DDL מסוג ALTER TABLE ... ALTER COLUMN:

    ALTER TABLE `PROJECT_ID.DATASET.TABLE`
    ALTER COLUMN FIELD_NAME SET DATA TYPE NEW_TYPE;

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫PROJECT_ID: מזהה הפרויקט שמכיל את הטבלה.
    • ‫DATASET: שם מערך הנתונים שמכיל את הטבלה.
    • ‫TABLE: שם הטבלה.
    • ‫FIELD_NAME: שם העמודה שרוצים לשנות.
    • ‫NEW_TYPE: סוג נתוני היעד.
  • אם המרת הסוג לא נתמכת במקום, צריך לשלוח שאילתה על הנתונים הקיימים עם ביטוי CAST מפורש, ולכתוב את התוצאות בטבלה חדשה או להחליף את הטבלה הקיימת. למידע נוסף, קראו את המאמר שינוי סוג הנתונים של עמודה.

המצב של השדה השתנה

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Field FIELD_NAME has changed mode from EXISTING_MODE to NEW_MODE

האבחון

הבקשה מנסה לשנות מצב עמודה שלא נתמך (לדוגמה, שינוי של NULLABLE ל-REQUIRED או של REPEATED ל-NULLABLE). השגיאה הזו מתרחשת גם אם משתמשים בהגדרת סכימה מוטבעת בכלי שורת הפקודה של BigQuery כשמגמישים עמודת REQUIRED בטבלה שמכילה עמודות REPEATED, כי הגדרות סכימה מוטבעות בכלי שורת הפקודה של BigQuery לא תומכות בשינוי טבלאות עם עמודות REPEATED.

רזולוציה

השינוי היחיד במצב שנתמך על ידי עדכונים במקום של סכימת BigQuery הוא הקלה במצב של עמודה מ-REQUIRED ל-NULLABLE. כדי לפתור את השגיאה הזו, מבצעים אחת מהפעולות הבאות:

  • אם אתם משנים את ההגדרה של עמודה מ-REQUIRED ל-NULLABLE, הריצו הצהרת DDL מסוג ALTER TABLE ... ALTER COLUMN ... DROP NOT NULL ב-GoogleSQL, או ספקו קובץ סכימה בפורמט JSON אם אתם מעדכנים את הסכימה באמצעות הפקודה bq update או ה-method‏ tables.patch ב-API. איך משנים את המצב של עמודה?
  • כדי לשנות את המצב של עמודה מ-NULLABLE ל-REQUIRED או מ-REPEATED ל-NULLABLE, צריך ליצור טבלה חדשה עם הסכימה המעודכנת ולהעתיק או לטעון את הנתונים לטבלה החדשה. להוראות, ראו שינוי סכימות של טבלאות.

אי אפשר להוסיף שדות

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Cannot add fields (field: FIELD_NAME)

האבחון

משימת טעינה או משימת שאילתה כוללת עמודה (FIELD_NAME) שלא קיימת בטבלת היעד, והוספת סכימה לא מופעלת בהגדרות המשימה.

רזולוציה

הפעלת הוספת סכימה במשימת הטעינה או השאילתה:

  • ב-API בארכיטקטורת REST או בספריות הלקוח, כוללים את ALLOW_FIELD_ADDITION במאפיין schemaUpdateOptions של הגדרת משימת הטעינה או השאילתה.
  • בכלי שורת הפקודה של BigQuery, מעבירים את הדגל --schema_update_option=ALLOW_FIELD_ADDITION.
  • לחלופין, אפשר להוסיף את העמודה לפני הרצת המשימה באמצעות ALTER TABLE ... ADD COLUMN.

אי אפשר להוסיף שדות חובה לסכימה קיימת

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Cannot add required fields to an existing schema. (field: FIELD_NAME)

האבחון

הבקשה שלכם מוסיפה עמודה חדשה לטבלה קיימת, כשהמצב של העמודה מוגדר כ-REQUIRED (NOT NULL). מכיוון שהשורות הקיימות בטבלה יקבלו ערכי NULL בעמודה החדשה שנוספה, BigQuery דוחה הוספה של עמודות REQUIRED ישירות דרך עדכוני סכימה.

רזולוציה

כדי לפתור את השגיאה הזו, מבצעים אחת מהפעולות הבאות:

  • מוסיפים את העמודה החדשה עם המצב NULLABLE במקום REQUIRED, ואז מריצים פקודת DML‏ UPDATE כדי לאכלס ערכים בשורות הקיימות.
  • כדי להוסיף את העמודה ולהקצות ערך ברירת מחדל, מבצעים את השלבים הבאים:

    1. מוסיפים את העמודה כעמודה מסוג NULLABLE.
    2. מגדירים את ערך ברירת המחדל של העמודה כדי שהוספות עתידיות יקבלו ערך באופן אוטומטי.
    3. מעדכנים את השורות הקיימות כדי לאכלס את ערך ברירת המחדל:

      ALTER TABLE `PROJECT_ID.DATASET.TABLE`
      ADD COLUMN FIELD_NAME DATA_TYPE;
      
      ALTER TABLE `PROJECT_ID.DATASET.TABLE`
      ALTER COLUMN FIELD_NAME SET DEFAULT DEFAULT_EXPRESSION;
      
      UPDATE `PROJECT_ID.DATASET.TABLE`
      SET FIELD_NAME = DEFAULT_EXPRESSION
      WHERE TRUE;

      מחליפים את מה שכתוב בשדות הבאים:

      • ‫PROJECT_ID: מזהה הפרויקט שמכיל את הטבלה.
      • ‫DATASET: שם מערך הנתונים שמכיל את הטבלה.
      • ‫TABLE: שם הטבלה.
      • ‫FIELD_NAME: שם העמודה החדשה.
      • ‫DATA_TYPE: סוג הנתונים בעמודה.
      • ‫DEFAULT_EXPRESSION: ביטוי ערך ברירת המחדל של העמודה.

השדה כבר קיים בסכימה

הודעת שגיאה

Field FIELD_NAME already exists in schema

האבחון

הסכימה שצוינה בבקשת ה-API, בקובץ הסכימה של JSON או בכותרת של קובץ המקור (כמו CSV או Parquet) מכילה שמות כפולים של עמודות. שמות העמודות ב-BigQuery הם לא תלויי-רישיות, ולכן אם מציינים גם את Field_A וגם את field_a באותה סכימה, השגיאה הזו מופיעה.

רזולוציה

בודקים את סכימת המקור ומסירים או משנים את השמות של העמודות הכפולות, כולל התנגשויות בין שמות שלא תלויים ברישיות.

אין תמיכה בעדכון של השוואת שדות

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Invalid schema update. Updating field collation is not supported. Field FIELD_NAME has changed collation from "EXISTING_COLLATION" to "NEW_COLLATION"

האבחון

אי אפשר לשנות או להסיר את מפרט ה-collation של עמודה קיימת במהלך עדכון סכימה. השגיאה הזו מתרחשת בדרך כלל כשאפליקציה מאחזרת סכימה של טבלה, משנה שדה אחר וכותבת את הסכימה בחזרה באמצעות גרסה ישנה יותר של ספריית לקוח שלא שומרת את מאפיין השדה collation (שולחת "" במקום "und:ci").

רזולוציה

כדי לפתור את השגיאה:

  • לשדרג את ספריית הלקוח של BigQuery לגרסה העדכנית ביותר, כדי לשמור על מאפייני collation הקיימים כשקוראים ומתקנים את המטא-נתונים של הטבלה.
  • אם אתם יוצרים מטען ייעודי (payload) של סכימת JSON באופן ידני, ודאו שהמאפיין collation בעמודות הקיימות תואם לסכימה הנוכחית של הטבלה.

אי אפשר לצמצם את הפרמטרים של הסוגים

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Narrowing type parameters is not compatible

האבחון

ההצהרה ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE מנסה להקטין את האורך המקסימלי, הדיוק או קנה המידה של סוג נתונים עם פרמטרים – לדוגמה, שינוי של STRING(100) ל-STRING(50) או הקטנת הפרמטרים של NUMERIC(P, S).

רזולוציה

ב-BigQuery אפשר רק להרחיב את הפרמטרים של הסוג בעמודה קיימת (למשל, להגדיל את STRING(50) ל-STRING(100)). כדי לאכוף פרמטרים צרים יותר של הסוג, צריך ליצור טבלה חדשה שמוגדרת עם הפרמטר הצר יותר של הסוג, ולהעתיק או לטעון את הנתונים לטבלה החדשה באמצעות שאילתת SELECT שמתאימה את הערכים לסוג הצר יותר (למשל, LEFT(FIELD_NAME, 50) לעמודה STRING). אם כותבים ערך STRING או BYTES שארוך מהאורך המקסימלי של העמודה, או ערך NUMERIC עם יותר ספרות ממה שמאפשרת רמת הדיוק, תוחזר שגיאה. ערכי NUMERIC עם יותר ספרות עשרוניות מהקנה מידה של העמודה מעוגלים. מידע נוסף זמין במאמר שינוי סכימות של טבלאות.

אי אפשר להוסיף שדה עם ערך ברירת מחדל

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Add field with default value to an existing table schema is not supported; Field: FIELD_NAME. ...

האבחון

משימת הטעינה או בקשת ה-API של tables.patch או tables.update מנסה להוסיף עמודה חדשה לטבלה קיימת, תוך ציון defaultValueExpression במטען הייעודי (payload) של סכימת ה-API. אי אפשר להוסיף עמודה חדשה עם ערך ברירת מחדל לטבלה קיימת בעדכון יחיד של סכימת API.

רזולוציה

במקום לציין את defaultValueExpression כשמוסיפים את העמודה בבקשת ה-API, קודם מוסיפים את העמודה ואז מגדירים את ערך ברירת המחדל שלה (למידע נוסף, ראו מגבלות):

  • אם עדיין לא הוספתם את העמודה, הריצו את ההצהרות הבאות ואז המשיכו את הטעינות בלי defaultValueExpression:

    ALTER TABLE `PROJECT_ID.DATASET.TABLE`
    ADD COLUMN FIELD_NAME DATA_TYPE;
    
    ALTER TABLE `PROJECT_ID.DATASET.TABLE`
    ALTER COLUMN FIELD_NAME SET DEFAULT DEFAULT_EXPRESSION;
    
    UPDATE `PROJECT_ID.DATASET.TABLE`
    SET FIELD_NAME = DEFAULT_EXPRESSION
    WHERE TRUE;

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫PROJECT_ID: מזהה הפרויקט שמכיל את הטבלה.
    • ‫DATASET: שם מערך הנתונים שמכיל את הטבלה.
    • ‫TABLE: שם הטבלה.
    • ‫FIELD_NAME: שם העמודה החדשה.
    • ‫DATA_TYPE: סוג הנתונים בעמודה.
    • ‫DEFAULT_EXPRESSION: ביטוי ערך ברירת המחדל של העמודה.
  • אם כבר הוספתם את העמודה על ידי שליחה מחדש של הבקשה בלי defaultValueExpression, צריך להריץ רק את ההצהרות ALTER COLUMN ... SET DEFAULT ו-UPDATE מהדוגמה הקודמת.

אין תמיכה בעדכון המאפיינים של עמודת זהות קיימת

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Updating an existing identity column's attributes is not supported. Field FIELD_NAME already has identity column info.

האבחון

הבקשה מנסה לשנות את המאפיינים של עמודת זהות קיימת באמצעות עדכון סכימה או תיקון API.

רזולוציה

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

שינוי שדה לא תואם בעמודה RECORD

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Incompatible field change within RECORD column

האבחון

ההצהרה ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE מציינת סוג STRUCT שלא תואם לסוג הקיים של העמודה. לדוגמה, הסוג החדש מוסיף או מסיר שדות משנה, משנה שדה משנה לסוג לא נתמך או מצמצם את הפרמטרים של הסוג של שדה משנה.

רזולוציה

משווים בין הסוג של STRUCT בהצהרת ALTER TABLE לבין הסכימה הקיימת של העמודה, ואז מבצעים אחת מהפעולות הבאות:

הגעת למגבלה המקסימלית של סכימות פיזיות שונות

הודעת שגיאה

Provided Schema does not match Table PROJECT_ID:DATASET.TABLE. Maximum limit on diverging physical schemas reached.

האבחון

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

רזולוציה

משתמשים בהצהרת ה-DDL של CREATE TABLE LIKE כדי ליצור מחדש את טבלת היעד, כך שהייצוג של הסכימה הפיזית שלה יתאים לסכימה של טבלת המקור, ואז מעתיקים או מוסיפים את הנתונים:

CREATE OR REPLACE TABLE `PROJECT_ID.DATASET.DESTINATION_TABLE`
LIKE `PROJECT_ID.DATASET.SOURCE_TABLE`;

INSERT INTO `PROJECT_ID.DATASET.DESTINATION_TABLE`
SELECT * FROM `PROJECT_ID.DATASET.SOURCE_TABLE`;

מחליפים את מה שכתוב בשדות הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט שמכיל את הטבלאות.
  • ‫DATASET: שם מערך הנתונים שמכיל את הטבלאות.
  • ‫DESTINATION_TABLE: השם של טבלת היעד שרוצים ליצור מחדש.
  • ‫SOURCE_TABLE: השם של טבלת המקור.

פתרון שגיאות שקשורות למגבלות על סכימות, קבצים ושגרות מקוננות

ב-BigQuery יש אכיפה של עומק הטמעה מקסימלי של 15 רמות לעמודות STRUCT (RECORD), קובצי טעינה מובְנים וארגומנטים מוטמעים של שגרות וסוגי החזרה. אם חורגים מהמגבלה של 15 רמות, מוחזרת שגיאת HTTP 400 Bad Request עם אחת מההודעות הבאות (כאשר MAX_DEPTH ו-MAX_LEVEL הם 15). במאמר יותר מדי תצוגות בתצוגות או פונקציות מתמידות בהגדרת המשתמש מוסבר על שגיאות שנגרמות בגלל חריגה מהמגבלה של 16 רמות בתצוגות לוגיות או בפונקציות מתמידות בהגדרת המשתמש (UDF).

הודעות שגיאה

  • Schema nested too deeply.
  • Schema nested too deeply for field FIELD_NAME, maximum allowed depth is MAX_DEPTH.
  • Field 'FIELD_NAME' is nested too deeply. It has definition level LEVEL while maximum allowed definition level is MAX_LEVEL.
  • Schema nested too deeply, at least LEVEL compared to the maximum allowed level of 15.
  • Routine TYPE_DESCRIPTION nested too deeply; max allowed depth: MAX_DEPTH

האבחון

עמודות מסוג STRUCT (RECORD) יכולות להכיל שדות RECORD בתצוגת עץ עד לעומק מקסימלי של 15 רמות, בלי קשר לשאלה אם השדות הם סקלריים (NULLABLE או REQUIRED) או מבוססי-מערך (REPEATED). באופן דומה, משימות טעינה וטבלאות חיצוניות של JSON,‏ Parquet ו-Avro אוכפות את מגבלת תצוגת העץ כשהן מנתחות מבנים בתצוגת עץ. בקובצי Parquet, המגבלה מוגדרת כרמת הגדרה מקסימלית ורמת חזרה מקסימלית.

בשגיאות של שגרות, TYPE_DESCRIPTION מזהה את הסוג בתצוגת עץ: argument type,‏ return type או return table type.

רזולוציה

אי אפשר להגדיל את המכסה הזו. כדי לפתור את השגיאה הזו, מבצעים אחת מהפעולות הבאות:

  • השטחת הסכימה או הגדרת סוג השגרה. לפרק היררכיות של STRUCT או ARRAY עם רמות עמוקות של הטמעה בסכימת הטבלה או בארגומנטים ובסוגי ההחזרה של השגרה, לטבלאות קשורות נפרדות, ולצרף אותן בזמן השאילתה. אפשר גם לקדם מאפיינים עם רמות עמוקות של הטמעה לעמודות ברמה גבוהה יותר.
  • משתמשים בסוג הנתונים המובנה JSON. אם הנתונים שלכם דורשים יותר מ-15 רמות של הטמעה, אחסנו את עצי המשנה המוטמעים עמוק בעמודה מסוג JSON (או STRING). עמודת JSON מאוחסנת כעמודה אחת בסכימת הטבלה, וכך נמנעת מגבלת הסכימה של 15 רמות של RECORD, ועדיין אפשר לחלץ נתיבים מוטמעים עמוק בזמן השאילתה באמצעות פונקציות ואופרטורים של גישה לשדות JSON.
  • עיבוד מראש של קובצי קלט לפני הטעינה. אם השגיאה מתרחשת במהלך משימת טעינה מקובצי JSON,‏ Parquet או Avro ב-Cloud Storage, צריך להוסיף שלב עיבוד מקדים במעלה הזרם כדי לשטח או לבצע סריאליזציה של מבנים בעומק של יותר מ-15 רמות לפני הטעינה שלהם ל-BigQuery.