שינוי סכמות של טבלאות

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

את רוב השינויים בסכימה שמתוארים במסמך הזה אפשר לבצע באמצעות הצהרות של שפת הגדרת נתונים (DDL) ב-SQL. הדוחות האלה לא כרוכים בחיובים.

כדי לשנות סכימה של טבלה בכל הדרכים שמתוארות בדף הזה, אפשר לייצא את נתוני הטבלה ל-Cloud Storage ואז לטעון את הנתונים לטבלה חדשה עם הגדרת הסכימה ששונתה. משימות הטעינה והחילוץ ב-BigQuery הן בחינם, אבל יש עלויות לאחסון הנתונים שיוצאו ב-Cloud Storage. בקטעים הבאים מתוארות דרכים אחרות לביצוע סוגים שונים של שינויים בסכימה.

עדכוני סכימה ב-BigQuery לא גורמים לאובדן נתונים.

הוספת עמודה

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

  • מוסיפים עמודה ריקה חדשה.
  • החלפת טבלה באמצעות משימת טעינה או משימת שאילתה.
  • להוסיף נתונים לטבלה באמצעות משימת טעינה או משימת שאילתה.

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

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

הוספת עמודה ריקה

אם מוסיפים עמודות חדשות לסכימת טבלה קיימת, העמודות חייבות להיות NULLABLE או REPEATED. אי אפשר להוסיף עמודת REQUIRED לסכימת טבלה קיימת. הוספת עמודה מסוג REQUIRED לסכימה של טבלה קיימת ב-API או בכלי שורת הפקודה של BigQuery תגרום לשגיאה. עם זאת, אפשר ליצור עמודת REQUIRED בתצוגת עץ כחלק משדה RECORD חדש. אפשר להוסיף עמודות REQUIRED רק כשיוצרים טבלה בזמן טעינת הנתונים, או כשיוצרים טבלה ריקה עם הגדרת סכימה.

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

המסוף

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בחלונית הימנית, לוחצים על Explorer:

    כפתור מודגש לחלונית Explorer.

    אם החלונית הימנית לא מוצגת, לוחצים על הרחבת החלונית הימנית כדי לפתוח אותה.

  3. בחלונית Explorer, מרחיבים את הפרויקט, לוחצים על Datasets ובוחרים קבוצת נתונים.

  4. לוחצים על סקירה כללית > טבלאות, ובוחרים את הטבלה.

  5. בחלונית הפרטים, לוחצים על Edit > Edit schema.

  6. בדף Current schema, בקטע New fields, לוחצים על Add field.

    • בשם, מקלידים את שם העמודה.
    • בשדה Type, בוחרים את סוג הנתונים.
    • בקטע Mode, בוחרים באפשרות NULLABLE או REPEATED.
  7. כשמסיימים להוסיף עמודות, לוחצים על שמירה.

SQL

משתמשים בהצהרת ה-DDL‏ ALTER TABLE ADD COLUMN:

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בעורך השאילתות, מזינים את ההצהרה הבאה:

    ALTER TABLE mydataset.mytable
    ADD COLUMN new_column STRING;

  3. ‫לוחצים על Run.

מידע נוסף על הרצת שאילתות זמין במאמר הרצת שאילתה אינטראקטיבית.

BQ

מפעילים את הפקודה bq update ומספקים קובץ סכימה בפורמט JSON. אם הטבלה שאתם מעדכנים נמצאת בפרויקט אחר מהפרויקט שמוגדר כברירת מחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

bq update PROJECT_ID:DATASET.TABLE SCHEMA

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

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

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

אם אתם מנסים להוסיף עמודות באמצעות הגדרת סכימה בתוך השורה, אתם צריכים לספק את הגדרת הסכימה המלאה, כולל העמודות החדשות. מכיוון שאי אפשר לציין מצבי עמודות באמצעות הגדרת סכימה מוטבעת, העדכון משנה כל עמודה קיימת של REPEATED ל-NULLABLE, מה שגורם לשגיאה הבאה: BigQuery error in update operation: Provided Schema does not match Table PROJECT_ID:dataset.table. Field field has changed mode from REPEATED to NULLABLE.

השיטה המועדפת להוספת עמודות לטבלה קיימת באמצעות כלי שורת הפקודה של BigQuery היא לספק קובץ סכימה בפורמט JSON.

כדי להוסיף עמודות ריקות לסכימה של טבלה באמצעות קובץ סכימת JSON:

  1. קודם כל, מפעילים את הפקודה bq show עם הדגל --schema וכותבים את הסכימה הקיימת של הטבלה לקובץ. אם הטבלה שאתם מעדכנים נמצאת בפרויקט אחר, ולא בפרויקט ברירת המחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

    bq show \
    --schema \
    --format=prettyjson \
    PROJECT_ID:DATASET.TABLE > SCHEMA

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

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

    לדוגמה, כדי לכתוב את הגדרת הסכימה של mydataset.mytable לקובץ, מזינים את הפקודה הבאה. ‫mydataset.mytable נמצא בפרויקט ברירת המחדל.

       bq show \
       --schema \
       --format=prettyjson \
       mydataset.mytable > /tmp/myschema.json
    
  2. פותחים את קובץ הסכימה בכלי לעריכת טקסט. הסכימה אמורה להיראות כך:

    [
      {
        "mode": "REQUIRED",
        "name": "column1",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "column2",
        "type": "FLOAT"
      },
      {
        "mode": "REPEATED",
        "name": "column3",
        "type": "STRING"
      }
    ]
    
  3. מוסיפים את העמודות החדשות לסוף הגדרת הסכימה. אם תנסו להוסיף עמודות חדשות במקום אחר במערך, תופיע השגיאה הבאה: BigQuery error in update operation: Precondition Failed. שינוי סדר הסכימה אחרי יצירת הטבלה לא משפיע על סדר העמודות או השדות בתצוגת עץ.

    באמצעות קובץ JSON, אתם יכולים לציין תיאורים, מצבי NULLABLE או REPEATED וסוגי RECORD לעמודות חדשות. לדוגמה, אם משתמשים בהגדרת הסכימה מהשלב הקודם, מערך ה-JSON החדש ייראה כך: בדוגמה הזו, נוספת עמודה חדשה מסוג NULLABLE בשם column4. column4 כולל תיאור.

      [
        {
          "mode": "REQUIRED",
          "name": "column1",
          "type": "STRING"
        },
        {
          "mode": "REQUIRED",
          "name": "column2",
          "type": "FLOAT"
        },
        {
          "mode": "REPEATED",
          "name": "column3",
          "type": "STRING"
        },
        {
          "description": "my new column",
          "mode": "NULLABLE",
          "name": "column4",
          "type": "STRING"
        }
      ]
      

    למידע נוסף על עבודה עם קובצי סכימה בפורמט JSON, קראו את המאמר ציון קובץ סכימה בפורמט JSON.

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

    bq update PROJECT_ID:DATASET.TABLE SCHEMA

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

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

    לדוגמה, מזינים את הפקודה הבאה כדי לעדכן את הגדרת הסכימה של mydataset.mytable בפרויקט שמוגדר כברירת מחדל. הנתיב לקובץ הסכימה במחשב המקומי הוא /tmp/myschema.json.

    bq update mydataset.mytable /tmp/myschema.json
    

API

מפעילים את השיטה tables.patch ומשתמשים במאפיין schema כדי להוסיף עמודות ריקות להגדרת הסכימה. מכיוון שה-method‏ tables.update מחליפה את כל משאב הטבלה, עדיף להשתמש ב-method‏ tables.patch.

המשך

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// updateTableAddColumn demonstrates modifying the schema of a table to append an additional column.
func updateTableAddColumn(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	tableRef := client.Dataset(datasetID).Table(tableID)
	meta, err := tableRef.Metadata(ctx)
	if err != nil {
		return err
	}
	newSchema := append(meta.Schema,
		&bigquery.FieldSchema{Name: "phone", Type: bigquery.StringFieldType},
	)
	update := bigquery.TableMetadataToUpdate{
		Schema: newSchema,
	}
	if _, err := tableRef.Update(ctx, update, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.FieldList;
import com.google.cloud.bigquery.LegacySQLTypeName;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.Table;
import java.util.ArrayList;
import java.util.List;

public class AddEmptyColumn {

  public static void runAddEmptyColumn() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableId = "MY_TABLE_NAME";
    String newColumnName = "NEW_COLUMN_NAME";
    addEmptyColumn(newColumnName, datasetName, tableId);
  }

  public static void addEmptyColumn(String newColumnName, String datasetName, String tableId) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      Table table = bigquery.getTable(datasetName, tableId);
      Schema schema = table.getDefinition().getSchema();
      FieldList fields = schema.getFields();

      // Create the new field/column
      Field newField = Field.of(newColumnName, LegacySQLTypeName.STRING);

      // Create a new schema adding the current fields, plus the new one
      List<Field> fieldList = new ArrayList<Field>();
      fields.forEach(fieldList::add);
      fieldList.add(newField);
      Schema newSchema = Schema.of(fieldList);

      // Update the table with the new schema
      Table updatedTable =
          table.toBuilder().setDefinition(StandardTableDefinition.of(newSchema)).build();
      updatedTable.update();
      System.out.println("Empty column successfully added to table");
    } catch (BigQueryException e) {
      System.out.println("Empty column was not added. \n" + e.toString());
    }
  }
}

Node.js

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במדריך למתחילים של BigQuery באמצעות ספריות לקוח. למידע נוסף, קראו את מאמרי העזרה של BigQuery Node.js API.

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.


// Import the Google Cloud client library and create a client
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function addEmptyColumn() {
  // Adds an empty column to the schema.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = 'my_dataset';
  // const tableId = 'my_table';
  const column = {name: 'size', type: 'STRING'};

  // Retrieve current table metadata
  const table = bigquery.dataset(datasetId).table(tableId);
  const [metadata] = await table.getMetadata();

  // Update table schema
  const schema = metadata.schema;
  const new_schema = schema;
  new_schema.fields.push(column);
  metadata.schema = new_schema;

  const [result] = await table.setMetadata(metadata);
  console.log(result.schema.fields);
}

Python

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

מוסיפים אובייקט SchemaField חדש לעותק של Table.schema, ואז מחליפים את הערך של המאפיין Table.schema בסכימה המעודכנת.
from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the table
#                  to add an empty column.
# table_id = "your-project.your_dataset.your_table_name"

table = client.get_table(table_id)  # Make an API request.

original_schema = table.schema
new_schema = original_schema[:]  # Creates a copy of the schema.
new_schema.append(bigquery.SchemaField("phone", "STRING"))

table.schema = new_schema
table = client.update_table(table, ["schema"])  # Make an API request.

if len(table.schema) == len(original_schema) + 1 == len(new_schema):
    print("A new column has been added.")
else:
    print("The column has not been added.")

הוספת עמודה משנית לעמודה מסוג RECORD

בנוסף להוספת עמודות חדשות לסכימה של טבלה, אפשר גם להוסיף עמודות חדשות בתצוגת עץ לעמודה מסוג RECORD. התהליך להוספת עמודה חדשה בתצוגת עץ דומה לתהליך להוספת עמודה חדשה.

המסוף

אי אפשר להוסיף שדה חדש בתצוגת עץ לעמודה קיימת מסוג RECORD באמצעות מסוף Google Cloud .

SQL

אי אפשר להוסיף שדה חדש בתצוגת עץ לעמודת RECORD קיימת באמצעות הצהרת SQL DDL.

BQ

מפעילים את הפקודה bq update ומספקים קובץ סכימה ב-JSON שמוסיף את השדה בתצוגת עץ להגדרת הסכימה של העמודה RECORD הקיימת. אם הטבלה שאתם מעדכנים נמצאת בפרויקט אחר מפרויקט ברירת המחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

bq update PROJECT_ID:DATASET.TABLE SCHEMA

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

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

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

כדי להוסיף עמודה בתצוגת עץ ל-RECORD באמצעות קובץ סכימה בפורמט JSON:

  1. קודם כל, מפעילים את הפקודה bq show עם הדגל --schema וכותבים את הסכימה הקיימת של הטבלה לקובץ. אם הטבלה שאתם מעדכנים נמצאת בפרויקט אחר מפרויקט ברירת המחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.TABLE.

    bq show \
    --schema \
    --format=prettyjson \
    PROJECT_ID:DATASET.TABLE > SCHEMA

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

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

    לדוגמה, כדי לכתוב את הגדרת הסכימה של mydataset.mytable לקובץ, מזינים את הפקודה הבאה. ‫mydataset.mytable נמצא בפרויקט ברירת המחדל.

    bq show \
    --schema \
    --format=prettyjson \
    mydataset.mytable > /tmp/myschema.json
    
  2. פותחים את קובץ הסכימה בכלי לעריכת טקסט. הסכימה אמורה להיראות כך: בדוגמה הזו, column3 היא עמודה חוזרת בתצוגת עץ. העמודות בתצוגת העץ הן nested1 ו-nested2. המערך fields מפרט את השדות שמוצבים בתוך column3.

    [
      {
        "mode": "REQUIRED",
        "name": "column1",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "column2",
        "type": "FLOAT"
      },
      {
        "fields": [
          {
            "mode": "NULLABLE",
            "name": "nested1",
            "type": "STRING"
          },
          {
            "mode": "NULLABLE",
            "name": "nested2",
            "type": "STRING"
          }
        ],
        "mode": "REPEATED",
        "name": "column3",
        "type": "RECORD"
      }
    ]
    
  3. מוסיפים את העמודה החדשה שנוצרה בסוף המערך fields. שדות בתצוגת עץ תמיד מתווספים בסוף השדה. בדוגמה הזו, nested3 היא העמודה החדשה בתצוגת עץ.

      [
        {
          "mode": "REQUIRED",
          "name": "column1",
          "type": "STRING"
        },
        {
          "mode": "REQUIRED",
          "name": "column2",
          "type": "FLOAT"
        },
        {
          "fields": [
            {
              "mode": "NULLABLE",
              "name": "nested1",
              "type": "STRING"
            },
            {
              "mode": "NULLABLE",
              "name": "nested2",
              "type": "STRING"
            },
            {
              "mode": "NULLABLE",
              "name": "nested3",
              "type": "STRING"
            }
          ],
          "mode": "REPEATED",
          "name": "column3",
          "type": "RECORD"
        }
      ]
      

    למידע נוסף על עבודה עם קובצי סכימה בפורמט JSON, קראו את המאמר ציון קובץ סכימה בפורמט JSON.

  4. אחרי שמעדכנים את קובץ הסכימה, מפעילים את הפקודה הבאה כדי לעדכן את הסכימה של הטבלה. אם הטבלה שאתם מעדכנים נמצאת בפרויקט אחר מפרויקט ברירת המחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

    bq update PROJECT_ID:DATASET.TABLE SCHEMA

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

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

    לדוגמה, מזינים את הפקודה הבאה כדי לעדכן את הגדרת הסכימה של mydataset.mytable בפרויקט שמוגדר כברירת מחדל. הנתיב לקובץ הסכימה במחשב המקומי הוא /tmp/myschema.json.

    bq update mydataset.mytable /tmp/myschema.json
    

API

מפעילים את ה-method‏ tables.patch ומשתמשים במאפיין schema כדי להוסיף את העמודות בתצוגת עץ להגדרת הסכימה. ה-method ‏tables.update מחליפה את כל משאב הטבלה, ולכן עדיף להשתמש ב-method ‏tables.patch.

הוספת עמודות כשמחליפים או מוסיפים נתונים

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

הוספת עמודות במשימת טעינה של הוספה (append)

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

  • זיהוי אוטומטי (לקובצי CSV ו-JSON)
  • סכימה שצוינה בקובץ סכימה של JSON (לקובצי CSV ו-JSON)
  • נתוני המקור שמתארים את עצמם בקובצי ייצוא של Avro, ‏ ORC, ‏ Parquet ו-Datastore

אם מציינים את הסכימה בקובץ JSON, צריך להגדיר בו את העמודות החדשות. אם הגדרות העמודות החדשות חסרות, תוחזר שגיאה כשמנסים להוסיף את הנתונים.

כשמוסיפים עמודות חדשות במהלך פעולת append, הערכים בעמודות החדשות מוגדרים כ-NULL בשורות הקיימות.

כדי להוסיף עמודה חדשה כשמצרפים נתונים לטבלה במהלך משימת טעינה, משתמשים באחת מהאפשרויות הבאות:

BQ

משתמשים בפקודה bq load כדי לטעון את הנתונים, ומציינים את הדגל --noreplace כדי לציין שאתם מוסיפים את הנתונים לטבלה קיימת.

אם הנתונים שאתם מוסיפים הם בפורמט CSV או JSON מופרד בשורה חדשה, ציינו את הדגל --autodetect כדי להשתמש בזיהוי אוטומטי של סכימה או ספקו את הסכימה בקובץ סכימה של JSON. אפשר להסיק באופן אוטומטי את העמודות שנוספו מקובצי ייצוא של Avro או Datastore.

מגדירים את הדגל --schema_update_option לערך ALLOW_FIELD_ADDITION כדי לציין שהנתונים שאתם מוסיפים מכילים עמודות חדשות.

אם הטבלה שאתם מוסיפים נמצאת במערך נתונים בפרויקט שהוא לא פרויקט ברירת המחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

(אופציונלי) מציינים את הדגל --location ומגדירים את הערך למיקום שלכם.

מזינים את הפקודה load באופן הבא:

bq --location=LOCATION load \
--noreplace \
--autodetect \
--schema_update_option=ALLOW_FIELD_ADDITION \
--source_format=FORMAT \
PROJECT_ID:DATASET.TABLE \
PATH_TO_SOURCE \
SCHEMA

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

  • ‫LOCATION: שם המיקום. הדגל --location הוא אופציונלי. לדוגמה, אם אתם משתמשים ב-BigQuery באזור טוקיו, הגדירו את הערך של הדגל ל-asia-northeast1. אפשר להגדיר ערך ברירת מחדל למיקום באמצעות הקובץ ‎.bigqueryrc.
  • ‫FORMAT: הפורמט של הסכימה. ‫NEWLINE_DELIMITED_JSON, CSV, AVRO, PARQUET, ORC או DATASTORE_BACKUP.
  • PROJECT_ID: מזהה הפרויקט.
  • ‫DATASET: שם קבוצת הנתונים שמכילה את הטבלה שמעדכנים.
  • ‫TABLE: שם הטבלה שמוסיפים.
  • ‫PATH_TO_SOURCE: URI של Cloud Storage שמוגדר באופן מלא, רשימה מופרדת בפסיקים של מזהי URI, או הנתיב לקובץ נתונים במחשב המקומי.
  • ‫SCHEMA: הנתיב לקובץ סכימה מקומי של JSON. קובץ סכימה נדרש רק לקובצי CSV ו-JSON כשלא מצוין --autodetect. סכימות של Avro ו-Datastore נגזרות מנתוני המקור.

דוגמאות:

מזינים את הפקודה הבאה כדי להוסיף קובץ נתונים מקומי בפורמט Avro,‏ /tmp/mydata.avro, ל-mydataset.mytable באמצעות משימת טעינה. מכיוון שאפשר להסיק סכימות באופן אוטומטי מנתוני Avro, אין צורך להשתמש בדגל --autodetect. ‫mydataset נמצא בפרויקט ברירת המחדל שלכם.

bq load \
--noreplace \
--schema_update_option=ALLOW_FIELD_ADDITION \
--source_format=AVRO \
mydataset.mytable \
/tmp/mydata.avro

מזינים את הפקודה הבאה כדי להוסיף קובץ נתונים בפורמט JSON מופרד בשורות חדשות ב-Cloud Storage ל-mydataset.mytable באמצעות משימת טעינה. הדגל --autodetect משמש לזיהוי העמודות החדשות. ‫mydataset נמצא בפרויקט שמוגדר כברירת מחדל.

bq load \
--noreplace \
--autodetect \
--schema_update_option=ALLOW_FIELD_ADDITION \
--source_format=NEWLINE_DELIMITED_JSON \
mydataset.mytable \
gs://mybucket/mydata.json

מזינים את הפקודה הבאה כדי להוסיף קובץ נתונים בפורמט JSON מופרד בשורות חדשות ב-Cloud Storage ל-mydataset.mytable באמצעות משימת טעינה. הסכימה שמכילה את העמודות החדשות מצוינת בקובץ סכימת JSON מקומי, /tmp/myschema.json. ‫mydataset נמצא ב-myotherproject, ולא בפרויקט שמוגדר כברירת מחדל.

bq load \
--noreplace \
--schema_update_option=ALLOW_FIELD_ADDITION \
--source_format=NEWLINE_DELIMITED_JSON \
myotherproject:mydataset.mytable \
gs://mybucket/mydata.json \
/tmp/myschema.json

API

מבצעים קריאה ל-method‏ jobs.insert. מגדירים משימה ב-load ומגדירים את המאפיינים הבאים:

  • מפנים לנתונים ב-Cloud Storage באמצעות המאפיין sourceUris.
  • מציינים את פורמט הנתונים על ידי הגדרת המאפיין sourceFormat.
  • מציינים את הסכימה במאפיין schema.
  • מציינים את אפשרות עדכון הסכימה באמצעות המאפיין schemaUpdateOptions.
  • מגדירים את מאפיין הכתיבה של טבלת היעד לערך WRITE_APPEND באמצעות המאפיין writeDisposition.

המשך

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"
	"os"

	"cloud.google.com/go/bigquery"
)

// createTableAndWidenLoad demonstrates augmenting a table's schema to add a new column via a load job.
func createTableAndWidenLoad(projectID, datasetID, tableID, filename string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType},
	}
	meta := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, meta); err != nil {
		return err
	}
	// Now, import data from a local file, but specify field additions are allowed.
	// Because the data has a second column (age), the schema is amended as part of
	// the load.
	f, err := os.Open(filename)
	if err != nil {
		return err
	}
	source := bigquery.NewReaderSource(f)
	source.AutoDetect = true   // Allow BigQuery to determine schema.
	source.SkipLeadingRows = 1 // CSV has a single header line.

	loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(source)
	loader.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION"}
	job, err := loader.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}
	if err := status.Err(); err != nil {
		return err
	}
	return nil
}

Java

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.FormatOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobId;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobInfo.SchemaUpdateOption;
import com.google.cloud.bigquery.JobInfo.WriteDisposition;
import com.google.cloud.bigquery.LegacySQLTypeName;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.TableId;
import com.google.common.collect.ImmutableList;
import java.util.UUID;

public class AddColumnLoadAppend {

  public static void runAddColumnLoadAppend() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String sourceUri = "/path/to/file.csv";
    addColumnLoadAppend(datasetName, tableName, sourceUri);
  }

  public static void addColumnLoadAppend(String datasetName, String tableName, String sourceUri)
      throws Exception {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);

      // Add a new column to a BigQuery table while appending rows via a load job.
      // 'REQUIRED' fields cannot  be added to an existing schema, so the additional column must be
      // 'NULLABLE'.
      Schema newSchema =
          Schema.of(
              Field.newBuilder("name", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.REQUIRED)
                  .build(),
              // Adding below additional column during the load job
              Field.newBuilder("post_abbr", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build());

      LoadJobConfiguration loadJobConfig =
          LoadJobConfiguration.builder(tableId, sourceUri)
              .setFormatOptions(FormatOptions.csv())
              .setWriteDisposition(WriteDisposition.WRITE_APPEND)
              .setSchema(newSchema)
              .setSchemaUpdateOptions(ImmutableList.of(SchemaUpdateOption.ALLOW_FIELD_ADDITION))
              .build();

      // Create a job ID so that we can safely retry.
      JobId jobId = JobId.of(UUID.randomUUID().toString());
      Job loadJob = bigquery.create(JobInfo.newBuilder(loadJobConfig).setJobId(jobId).build());

      // Load data from a GCS parquet file into the table
      // Blocks until this load table job completes its execution, either failing or succeeding.
      Job completedJob = loadJob.waitFor();

      // Check for errors
      if (completedJob == null) {
        throw new Exception("Job not executed since it no longer exists.");
      } else if (completedJob.getStatus().getError() != null) {
        // You can also look at queryJob.getStatus().getExecutionErrors() for all
        // errors, not just the latest one.
        throw new Exception(
            "BigQuery was unable to load into the table due to an error: \n"
                + loadJob.getStatus().getError());
      }
      System.out.println("Column successfully added during load append job");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Column not added during load append \n" + e.toString());
    }
  }
}

Node.js

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במדריך למתחילים של BigQuery באמצעות ספריות לקוח. למידע נוסף, קראו את מאמרי העזרה של BigQuery Node.js API.

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

// Import the Google Cloud client libraries
const {BigQuery} = require('@google-cloud/bigquery');

// Instantiate client
const bigquery = new BigQuery();

async function addColumnLoadAppend() {
  // Adds a new column to a BigQuery table while appending rows via a load job.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const fileName = '/path/to/file.csv';
  // const datasetId = 'my_dataset';
  // const tableId = 'my_table';

  // In this example, the existing table contains only the 'Name', 'Age',
  // & 'Weight' columns. 'REQUIRED' fields cannot  be added to an existing
  // schema, so the additional column must be 'NULLABLE'.
  const schema = 'Name:STRING, Age:INTEGER, Weight:FLOAT, IsMagic:BOOLEAN';

  // Retrieve destination table reference
  const [table] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .get();
  const destinationTableRef = table.metadata.tableReference;

  // Set load job options
  const options = {
    schema: schema,
    schemaUpdateOptions: ['ALLOW_FIELD_ADDITION'],
    writeDisposition: 'WRITE_APPEND',
    destinationTable: destinationTableRef,
  };

  // Load data from a local file into the table
  const [job] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .load(fileName, options);

  console.log(`Job ${job.id} completed.`);
  console.log(`New Schema:`);
  console.log(job.configuration.load.schema.fields);

  // Check the job's status for errors
  const errors = job.status.errors;
  if (errors && errors.length > 0) {
    throw errors;
  }
}

Python

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

# from google.cloud import bigquery
# client = bigquery.Client()
# project = client.project
# dataset_ref = bigquery.DatasetReference(project, 'my_dataset')
# filepath = 'path/to/your_file.csv'

# Retrieves the destination table and checks the length of the schema
table_id = "my_table"
table_ref = dataset_ref.table(table_id)
table = client.get_table(table_ref)
print("Table {} contains {} columns.".format(table_id, len(table.schema)))

# Configures the load job to append the data to the destination table,
# allowing field addition
job_config = bigquery.LoadJobConfig()
job_config.write_disposition = bigquery.WriteDisposition.WRITE_APPEND
job_config.schema_update_options = [
    bigquery.SchemaUpdateOption.ALLOW_FIELD_ADDITION
]
# In this example, the existing table contains only the 'full_name' column.
# 'REQUIRED' fields cannot be added to an existing schema, so the
# additional column must be 'NULLABLE'.
job_config.schema = [
    bigquery.SchemaField("full_name", "STRING", mode="REQUIRED"),
    bigquery.SchemaField("age", "INTEGER", mode="NULLABLE"),
]
job_config.source_format = bigquery.SourceFormat.CSV
job_config.skip_leading_rows = 1

with open(filepath, "rb") as source_file:
    job = client.load_table_from_file(
        source_file,
        table_ref,
        location="US",  # Must match the destination dataset location.
        job_config=job_config,
    )  # API request

job.result()  # Waits for table load to complete.
print(
    "Loaded {} rows into {}:{}.".format(
        job.output_rows, dataset_id, table_ref.table_id
    )
)

# Checks the updated length of the schema
table = client.get_table(table)
print("Table {} now contains {} columns.".format(table_id, len(table.schema)))

הוספת עמודות במשימת הוספה של שאילתה

אפשר להוסיף עמודות לטבלה כשמצרפים אליה תוצאות של שאילתה.

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

כדי להוסיף עמודה חדשה כשמצרפים נתונים לטבלה במהלך משימת שאילתה, בוחרים באחת מהאפשרויות הבאות:

BQ

משתמשים בפקודה bq query כדי לשלוח שאילתה על הנתונים, ומציינים את הדגל --destination_table כדי לציין לאיזו טבלה אתם מוסיפים את הנתונים.

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

מגדירים את הדגל --schema_update_option לערך ALLOW_FIELD_ADDITION כדי לציין שתוצאות השאילתה שאתם מוסיפים מכילות עמודות חדשות.

מציינים את הדגל use_legacy_sql=false כדי להשתמש בתחביר GoogleSQL בשאילתה.

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

(אופציונלי) מציינים את הדגל --location ומגדירים את הערך למיקום שלכם.

bq --location=LOCATION query \
--destination_table PROJECT_ID:DATASET.TABLE \
--append_table \
--schema_update_option=ALLOW_FIELD_ADDITION \
--use_legacy_sql=false \
'QUERY'

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

  • ‫LOCATION: שם המיקום. הדגל --location הוא אופציונלי. לדוגמה, אם אתם משתמשים ב-BigQuery באזור טוקיו, הגדירו את הערך של הדגל ל-asia-northeast1. אפשר להגדיר ערך ברירת מחדל למיקום באמצעות הקובץ ‎.bigqueryrc. שימו לב שאי אפשר לצרף תוצאות של שאילתה לטבלה במיקום אחר.
  • PROJECT_ID: מזהה הפרויקט.
  • ‫dataset: שם קבוצת הנתונים שמכילה את הטבלה שמוסיפים.
  • ‫TABLE: שם הטבלה שמוסיפים.
  • ‫QUERY: שאילתה בתחביר GoogleSQL.

דוגמאות:

מזינים את הפקודה הבאה כדי לשלוח שאילתה ל-mydataset.mytable בפרויקט ברירת המחדל, ולהוסיף את תוצאות השאילתה ל-mydataset.mytable2 (גם בפרויקט ברירת המחדל).

bq query \
--destination_table mydataset.mytable2 \
--append_table \
--schema_update_option=ALLOW_FIELD_ADDITION \
--use_legacy_sql=false \
'SELECT
   column1,column2
 FROM
   mydataset.mytable'

מזינים את הפקודה הבאה כדי לשלוח שאילתה ל-mydataset.mytable בפרויקט ברירת המחדל, ולהוסיף את תוצאות השאילתה ל-mydataset.mytable2 ב-myotherproject.

bq query \
--destination_table myotherproject:mydataset.mytable2 \
--append_table \
--schema_update_option=ALLOW_FIELD_ADDITION \
--use_legacy_sql=false \
'SELECT
   column1,column2
 FROM
   mydataset.mytable'

API

מבצעים קריאה ל-method‏ jobs.insert. מגדירים משימה ב-query ומגדירים את המאפיינים הבאים:

  • מציינים את טבלת היעד באמצעות המאפיין destinationTable.
  • מגדירים את מאפיין הכתיבה של טבלת היעד לערך WRITE_APPEND באמצעות המאפיין writeDisposition.
  • מציינים את אפשרות עדכון הסכימה באמצעות המאפיין schemaUpdateOptions.
  • מציינים את שאילתת GoogleSQL באמצעות המאפיין query.

המשך

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// createTableAndWidenQuery demonstrates how the schema of a table can be modified to add columns by appending
// query results that include the new columns.
func createTableAndWidenQuery(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	// First, we create a sample table.
	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType, Required: true},
		{Name: "age", Type: bigquery.IntegerFieldType, Required: true},
	}
	original := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, original); err != nil {
		return err
	}
	// Our table has two columns.  We'll introduce a new favorite_color column via
	// a subsequent query that appends to the table.
	q := client.Query("SELECT \"Timmy\" as full_name, 85 as age, \"Blue\" as favorite_color")
	q.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION"}
	q.QueryConfig.Dst = client.Dataset(datasetID).Table(tableID)
	q.WriteDisposition = bigquery.WriteAppend
	q.Location = "US"
	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	_, err = job.Wait(ctx)
	if err != nil {
		return err
	}
	return nil
}

Java

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobInfo.SchemaUpdateOption;
import com.google.cloud.bigquery.JobInfo.WriteDisposition;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableResult;
import com.google.common.collect.ImmutableList;

public class RelaxTableQuery {

  public static void runRelaxTableQuery() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    relaxTableQuery(projectId, datasetName, tableName);
  }

  // To relax all columns in a destination table when you append data to it during a query job
  public static void relaxTableQuery(String projectId, String datasetName, String tableName)
      throws Exception {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);

      String sourceTable = "`" + projectId + "." + datasetName + "." + tableName + "`";
      String query = "SELECT word FROM " + sourceTable + " WHERE word like '%is%'";

      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              // Use standard SQL syntax for queries.
              // See: https://cloud.google.com/bigquery/sql-reference/
              .setUseLegacySql(false)
              .setSchemaUpdateOptions(ImmutableList.of(SchemaUpdateOption.ALLOW_FIELD_RELAXATION))
              .setWriteDisposition(WriteDisposition.WRITE_APPEND)
              .setDestinationTable(tableId)
              .build();

      Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).build());

      queryJob = queryJob.waitFor();

      // Check for errors
      if (queryJob == null) {
        throw new Exception("Job no longer exists");
      } else if (queryJob.getStatus().getError() != null) {
        // You can also look at queryJob.getStatus().getExecutionErrors() for all
        // errors, not just the latest one.
        throw new Exception(queryJob.getStatus().getError().toString());
      }

      // Get the results.
      TableResult results = queryJob.getQueryResults();

      // Print all pages of the results.
      results
          .iterateAll()
          .forEach(
              rows -> {
                rows.forEach(row -> System.out.println("row: " + row.toString()));
              });

      System.out.println("Successfully relaxed all columns in destination table during query job");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Columns not relaxed during query job \n" + e.toString());
    }
  }
}

Node.js

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במדריך למתחילים של BigQuery באמצעות ספריות לקוח. למידע נוסף, קראו את מאמרי העזרה של BigQuery Node.js API.

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

// Import the Google Cloud client libraries
const {BigQuery} = require('@google-cloud/bigquery');

// Instantiate client
const bigquery = new BigQuery();

async function addColumnQueryAppend() {
  // Adds a new column to a BigQuery table while appending rows via a query job.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = 'my_dataset';
  // const tableId = 'my_table';

  // Retrieve destination table reference
  const [table] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .get();
  const destinationTableRef = table.metadata.tableReference;

  // In this example, the existing table contains only the 'name' column.
  // 'REQUIRED' fields cannot  be added to an existing schema,
  // so the additional column must be 'NULLABLE'.
  const query = `SELECT name, year
    FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
    WHERE state = 'TX'
    LIMIT 10`;

  // Set load job options
  const options = {
    query: query,
    schemaUpdateOptions: ['ALLOW_FIELD_ADDITION'],
    writeDisposition: 'WRITE_APPEND',
    destinationTable: destinationTableRef,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
  };

  const [job] = await bigquery.createQueryJob(options);
  console.log(`Job ${job.id} started.`);

  // Wait for the query to finish
  const [rows] = await job.getQueryResults();
  console.log(`Job ${job.id} completed.`);

  // Print the results
  console.log('Rows:');
  rows.forEach(row => console.log(row));
}

Python

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the destination table.
# table_id = "your-project.your_dataset.your_table_name"

# Retrieves the destination table and checks the length of the schema.
table = client.get_table(table_id)  # Make an API request.
print("Table {} contains {} columns".format(table_id, len(table.schema)))

# Configures the query to append the results to a destination table,
# allowing field addition.
job_config = bigquery.QueryJobConfig(
    destination=table_id,
    schema_update_options=[bigquery.SchemaUpdateOption.ALLOW_FIELD_ADDITION],
    write_disposition=bigquery.WriteDisposition.WRITE_APPEND,
)

# Start the query, passing in the extra configuration.
client.query_and_wait(
    # In this example, the existing table contains only the 'full_name' and
    # 'age' columns, while the results of this query will contain an
    # additional 'favorite_color' column.
    'SELECT "Timmy" as full_name, 85 as age, "Blue" as favorite_color;',
    job_config=job_config,
)  # Make an API request and wait for job to complete.

# Checks the updated length of the schema.
table = client.get_table(table_id)  # Make an API request.
print("Table {} now contains {} columns".format(table_id, len(table.schema)))

שינוי שם של עמודה

כדי לשנות שם של עמודה בטבלה, משתמשים בהצהרת ה-DDL‏ ALTER TABLE RENAME COLUMN. בדוגמה הבאה, השם של העמודה old_name משתנה ל-new_name ב-mytable:

ALTER TABLE mydataset.mytable
  RENAME COLUMN old_name TO new_name;

מידע נוסף על הצהרות ALTER TABLE RENAME COLUMN זמין במאמר פרטי DDL.

שינוי סוג הנתונים של עמודה

אי אפשר לשנות את סוג הנתונים של עמודה באמצעות מסוף Google Cloud , כלי שורת הפקודה של BigQuery או BigQuery API. אם תנסו לעדכן טבלה על ידי החלת סכימה שמציינת סוג נתונים חדש לעמודה, תוחזר שגיאה.

שינוי סוג הנתונים של עמודה באמצעות הצהרת DDL

אתם יכולים להשתמש ב-GoogleSQL כדי לבצע שינויים מסוימים בסוג הנתונים של עמודה. למידע נוסף ולרשימה מלאה של המרות נתמכות של סוגי נתונים, קראו את הצהרת ה-DDL של ALTER COLUMN SET DATA TYPE.

בדוגמה הבאה נוצרת טבלה עם עמודה מסוג INT64, ואז הסוג מתעדכן ל-NUMERIC:

CREATE TABLE mydataset.mytable(c1 INT64);

ALTER TABLE mydataset.mytable
ALTER COLUMN c1 SET DATA TYPE NUMERIC;

בדוגמה הבאה נוצרת טבלה עם עמודה בתצוגת עץ עם שני שדות, ואז מתעדכן הסוג של אחת מהעמודות מ-INT ל-NUMERIC:

CREATE TABLE mydataset.mytable(s1 STRUCT<a INT64, b STRING>);

ALTER TABLE mydataset.mytable ALTER COLUMN s1
SET DATA TYPE STRUCT<a NUMERIC, b STRING>;

שינוי סוגי העמודות המשניות

בשינויים מורכבים של סכימות בתצוגת עץ, כמו שינוי של שדה בתוך מערך של STRUCT, אין תמיכה בהצהרת DDL של ALTER TABLE. כדי לעקוף את הבעיה, אפשר להשתמש בהצהרה CREATE OR REPLACE TABLE עם הצהרת SELECT כדי לשנות את הסכימה המקוננת.

בדוגמה הבאה אפשר לראות איך משנים עמודה במערך של STRUCTS:

נניח שיש טבלה samples.test עם הסכימה והנתונים הבאים:

CREATE OR REPLACE TABLE
  samples.test(D STRUCT <L ARRAY<STRUCT<R STRING, U STRING, V STRING>>, F STRING>);

INSERT INTO
  samples.test(D)
VALUES
  (STRUCT([STRUCT("r1", "u1", "v1"), STRUCT("r2", "u2", "v2")], "f1"));

התוצאה אמורה להיראות כך:

+----------------------------------------------------------------------------+
|                                     D                                      |
+----------------------------------------------------------------------------+
| {"L":[{"R":"r1","U":"u1","V":"v1"},{"R":"r2","U":"u2","V":"v2"}],"F":"f1"} |
+----------------------------------------------------------------------------+

נניח שאתם צריכים לשנות את סוג השדה U במערך המוטמע של STRUCT ל-STRUCT<W STRING>. הצהרת ה-SQL הבאה מדגימה איך לעשות זאת:

CREATE OR REPLACE TABLE
  samples.new_table AS
SELECT
  STRUCT(ARRAY(
    SELECT
      STRUCT(tmp.R,
        STRUCT(tmp.U AS W) AS U,
        tmp.V)
    FROM
      UNNEST(t.D.L) AS tmp) AS L,
    t.D.F) AS D
FROM
  samples.test AS t

ההצהרה הזו יוצרת טבלה חדשה, samples.new_table, עם סכימת היעד. הפונקציה UNNEST מרחיבה את מערך ה-STRUCT בתוך t.D.L. הביטוי STRUCT(tmp.U AS W) AS U יוצר את ה-STRUCT החדש עם השדה W, שמאוכלס בערך מהשדה המקורי U. הסכימה והנתונים של הטבלה שנוצרה, samples.new_table, הם:

+----------------------------------------------------------------------------------------+
|                                           D                                            |
+----------------------------------------------------------------------------------------+
| {"L":[{"R":"r1","U":{"W":"u1"},"V":"v1"},{"R":"r2","U":{"W":"u2"},"V":"v2"}],"F":"f1"} |
+----------------------------------------------------------------------------------------+

המרת סוג הנתונים של עמודה

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

בדוגמה הבאה מוצגת שאילתת SQL שבוחרת את כל הנתונים מ-column_two ומ-column_three ב-mydataset.mytable וממירה את column_one מ-DATE ל-STRING. תוצאת השאילתה משמשת להחלפת הטבלה הקיימת. הטבלה שהוחלפה מאחסנת את column_one כסוג נתונים STRING.

כשמשתמשים ב-CAST, השאילתה עלולה להיכשל אם BigQuery לא יכול לבצע את ההמרה. לפרטים על כללי ההמרה ב-GoogleSQL, קראו את המאמר המרה.

המסוף

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בעורך השאילתות, מזינים את השאילתה הבאה כדי לבחור את כל הנתונים מ-column_two ומ-column_three ב-mydataset.mytable, ולהמיר את column_one מ-DATE ל-STRING. השאילתה משתמשת בכינוי כדי להמיר את column_one עם אותו שם. ‫mydataset.mytable נמצא בפרויקט שמוגדר כברירת מחדל.

    SELECT
     column_two,
     column_three,
     CAST(column_one AS STRING) AS column_one
    FROM
     mydataset.mytable;
  3. לוחצים על עריכה > הגדרות השאילתה.

  4. בקטע Destination:

    1. בוחרים באפשרות Set a destination table for query results.

    2. בשדה Project name, משאירים את הערך שמוגדר לפרויקט ברירת המחדל. זה הפרויקט שמכיל את mydataset.mytable.

    3. בקטע Dataset, בוחרים באפשרות mydataset.

    4. בשדה Table Id, מזינים mytable.

    5. בקטע Destination table write preference, בוחרים באפשרות Overwrite table. האפשרות הזו מחליפה את mytable בתוצאות השאילתה.

  5. אם רוצים, בוחרים את המיקום של הנתונים.

  6. כדי לעדכן את ההגדרות, לוחצים על שמירה.

  7. ‫לוחצים על Run.

    כשמשימת השאילתה מסתיימת, סוג הנתונים של column_one הוא STRING.

BQ

מזינים את הפקודה הבאה של bq query כדי לבחור את כל הנתונים מ-column_two ומ-column_three ב-mydataset.mytable, ולהמיר את column_one מ-DATE ל-STRING. השאילתה משתמשת בכינוי כדי להמיר את column_one עם אותו שם. ‫mydataset.mytable נמצא בפרויקט שמוגדר כברירת מחדל.

תוצאות השאילתה נכתבות ב-mydataset.mytable באמצעות הדגל --destination_table, והדגל --replace משמש להחלפת mytable. מציינים את הדגל use_legacy_sql=false כדי להשתמש בתחביר של GoogleSQL.

אפשר גם להוסיף את הדגל --location ולהגדיר את הערך למיקום שלכם.

bq query \
    --destination_table mydataset.mytable \
    --replace \
    --use_legacy_sql=false \
'SELECT
  column_two,
  column_three,
  CAST(column_one AS STRING) AS column_one
FROM
  mydataset.mytable'

API

כדי לבחור את כל הנתונים מ-column_two ומ-column_three ב-mydataset.mytable ולהמיר את column_one מ-DATE ל-STRING, מפעילים את ה-method‏ jobs.insert ומגדירים משימת query. אם רוצים, מציינים את המיקום במאפיין location בקטע jobReference.

שאילתת ה-SQL שבה משתמשים במשימת השאילתה היא SELECT column_two, column_three, CAST(column_one AS STRING) AS column_one FROM mydataset.mytable. השאילתה משתמשת בכינוי כדי להמיר את column_one עם אותו שם.

כדי להחליף את mytable בתוצאות השאילתה, צריך לכלול את mydataset.mytable במאפיין configuration.query.destinationTable ולציין את WRITE_TRUNCATE במאפיין configuration.query.writeDisposition.

שינוי המצב של עמודה

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

הוספת עמודה NULLABLE בטבלה קיימת

כדי לשנות את המצב של עמודה מ-REQUIRED ל-NULLABLE, בוחרים באחת מהאפשרויות הבאות:

המסוף

  1. נכנסים לדף BigQuery.

    כניסה ל-BigQuery

  2. בחלונית הימנית, לוחצים על Explorer:

    כפתור מודגש לחלונית Explorer.

  3. בחלונית Explorer, מרחיבים את הפרויקט, לוחצים על Datasets ובוחרים קבוצת נתונים.

  4. לוחצים על סקירה כללית > טבלאות, ובוחרים את הטבלה.

  5. בחלונית הפרטים, לוחצים על Edit > Edit schema.

  6. בדף Current schema, מאתרים את השדה שרוצים לשנות.

  7. ברשימה הנפתחת Mode של השדה הזה, בוחרים באפשרות NULLABLE.

  8. כדי לעדכן את ההגדרות, לוחצים על שמירה.

SQL

משתמשים בהצהרת ה-DDL‏ ALTER COLUMN DROP NOT NULL. בדוגמה הבאה משנים את המצב של העמודה mycolumn מ-REQUIRED ל-NULLABLE:

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בעורך השאילתות, מזינים את ההצהרה הבאה:

    ALTER TABLE mydataset.mytable
    ALTER COLUMN mycolumn
    DROP NOT NULL;

  3. ‫לוחצים על Run.

מידע נוסף על הרצת שאילתות זמין במאמר הרצת שאילתה אינטראקטיבית.

BQ

  1. קודם כל, מפעילים את הפקודה bq show עם הדגל --schema וכותבים את הסכימה הקיימת של הטבלה לקובץ. אם הטבלה שאתם מעדכנים נמצאת בפרויקט אחר מהפרויקט שמוגדר כברירת מחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

    bq show \
    --schema \
    --format=prettyjson \
    PROJECT_ID:DATASET.TABLE > SCHEMA_FILE

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

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

    לדוגמה, כדי לכתוב את הגדרת הסכימה של mydataset.mytable לקובץ, מזינים את הפקודה הבאה. ‫mydataset.mytable נמצא בפרויקט ברירת המחדל.

      bq show \
      --schema \
      --format=prettyjson \
      mydataset.mytable > /tmp/myschema.json
    
  2. פותחים את קובץ הסכימה בכלי לעריכת טקסט. הסכימה אמורה להיראות כך:

    [
      {
        "mode": "REQUIRED",
        "name": "column1",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "column2",
        "type": "FLOAT"
      },
      {
        "mode": "REPEATED",
        "name": "column3",
        "type": "STRING"
      }
    ]
    
  3. שינוי המצב של עמודה קיימת מ-REQUIRED ל-NULLABLE. בדוגמה הזו, המצב של column1 הוא "רגוע".

    [
      {
        "mode": "NULLABLE",
        "name": "column1",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "column2",
        "type": "FLOAT"
      },
      {
        "mode": "REPEATED",
        "name": "column3",
        "type": "STRING"
      }
    ]
    

    למידע נוסף על עבודה עם קובצי סכימה של JSON, ראו ציון קובץ סכימה של JSON.

  4. אחרי שמעדכנים את קובץ הסכימה, מפעילים את הפקודה הבאה כדי לעדכן את הסכימה של הטבלה. אם הטבלה שאתם מעדכנים נמצאת בפרויקט אחר מפרויקט ברירת המחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

    bq update PROJECT_ID:DATASET.TABLE SCHEMA

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

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

    לדוגמה, מזינים את הפקודה הבאה כדי לעדכן את הגדרת הסכימה של mydataset.mytable בפרויקט שמוגדר כברירת מחדל. הנתיב לקובץ הסכימה במחשב המקומי הוא /tmp/myschema.json.

      bq update mydataset.mytable /tmp/myschema.json
    

API

קוראים ל-tables.patch ומשתמשים במאפיין schema כדי לשנות עמודת REQUIRED ל-NULLABLE בהגדרת הסכימה. השיטה tables.update מחליפה את כל משאב הטבלה, ולכן עדיף להשתמש בשיטה tables.patch.

המשך

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// relaxTableAPI demonstrates modifying the schema of a table to remove the requirement that columns allow
// no NULL values.
func relaxTableAPI(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydatasetid"
	// tableID := "mytableid"
	ctx := context.Background()

	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	// Setup: We first create a table with a schema that's restricts NULL values.
	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType, Required: true},
		{Name: "age", Type: bigquery.IntegerFieldType, Required: true},
	}
	original := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	if err := client.Dataset(datasetID).Table(tableID).Create(ctx, original); err != nil {
		return err
	}

	tableRef := client.Dataset(datasetID).Table(tableID)
	meta, err := tableRef.Metadata(ctx)
	if err != nil {
		return err
	}
	// Iterate through the schema to set all Required fields to false (nullable).
	var relaxed bigquery.Schema
	for _, v := range meta.Schema {
		v.Required = false
		relaxed = append(relaxed, v)
	}
	newMeta := bigquery.TableMetadataToUpdate{
		Schema: relaxed,
	}
	if _, err := tableRef.Update(ctx, newMeta, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.LegacySQLTypeName;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.Table;

public class RelaxColumnMode {

  public static void runRelaxColumnMode() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableId = "MY_TABLE_NAME";
    relaxColumnMode(datasetName, tableId);
  }

  public static void relaxColumnMode(String datasetName, String tableId) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      Table table = bigquery.getTable(datasetName, tableId);

      // Create new relaxed schema based on the existing table schema
      Schema relaxedSchema =
          Schema.of(
              // The only supported modification you can make to a column's mode is changing it from
              // REQUIRED to NULLABLE
              // Changing a column's mode from REQUIRED to NULLABLE is also called column relaxation
              // INFO: LegacySQLTypeName will be updated to StandardSQLTypeName in release 1.103.0
              Field.newBuilder("word", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build(),
              Field.newBuilder("word_count", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build(),
              Field.newBuilder("corpus", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build(),
              Field.newBuilder("corpus_date", LegacySQLTypeName.STRING)
                  .setMode(Field.Mode.NULLABLE)
                  .build());

      // Update the table with the new schema
      Table updatedTable =
          table.toBuilder().setDefinition(StandardTableDefinition.of(relaxedSchema)).build();
      updatedTable.update();
      System.out.println("Table schema successfully relaxed.");
    } catch (BigQueryException e) {
      System.out.println("Table schema not relaxed \n" + e.toString());
    }
  }
}

Node.js

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במדריך למתחילים של BigQuery באמצעות ספריות לקוח. למידע נוסף, קראו את מאמרי העזרה של BigQuery Node.js API.

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

// Import the Google Cloud client library and create a client
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function relaxColumn() {
  /**
   * Changes columns from required to nullable.
   * Assumes existing table with the following schema:
   * [{name: 'Name', type: 'STRING', mode: 'REQUIRED'},
   * {name: 'Age', type: 'INTEGER'},
   * {name: 'Weight', type: 'FLOAT'},
   * {name: 'IsMagic', type: 'BOOLEAN'}];
   */

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = 'my_dataset';
  // const tableId = 'my_table';

  const newSchema = [
    {name: 'Name', type: 'STRING', mode: 'NULLABLE'},
    {name: 'Age', type: 'INTEGER'},
    {name: 'Weight', type: 'FLOAT'},
    {name: 'IsMagic', type: 'BOOLEAN'},
  ];

  // Retrieve current table metadata
  const table = bigquery.dataset(datasetId).table(tableId);
  const [metadata] = await table.getMetadata();

  // Update schema
  metadata.schema = newSchema;
  const [apiResponse] = await table.setMetadata(metadata);

  console.log(apiResponse.schema.fields);
}

Python

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

מחליפים את המאפיין Table.schema ברשימה של אובייקטים מסוג SchemaField, כשהמאפיין mode מוגדר לערך 'NULLABLE'

from google.cloud import bigquery

client = bigquery.Client()

# TODO(dev): Change table_id to full name of the table you want to create.
table_id = "your-project.your_dataset.your_table"

table = client.get_table(table_id)
new_schema = []
for field in table.schema:
    if field.mode != "REQUIRED":
        new_schema.append(field)
    else:
        # SchemaField properties cannot be edited after initialization.
        # To make changes, construct new SchemaField objects.
        new_field = field.to_api_repr()
        new_field["mode"] = "NULLABLE"
        relaxed_field = bigquery.SchemaField.from_api_repr(new_field)
        new_schema.append(relaxed_field)

table.schema = new_schema
table = client.update_table(table, ["schema"])

print(f"Updated {table_id} schema: {table.schema}.")

יצירת עמודה NULLABLE באמצעות משימת טעינה של הוספה

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

  • כשמוסיפים נתונים מקובצי CSV ו-JSON, אפשר להגמיש את המצב של עמודות ספציפיות על ידי ציון קובץ סכימת JSON.
  • כשמוסיפים נתונים מקובצי Avro, ‏ ORC או Parquet, צריך להרפות את העמודות ל-NULL בסכימה, ולאפשר להסקת הסכימה לזהות את העמודות שהורפו.

כדי להרפות עמודה מ-REQUIRED ל-NULLABLE כשמוסיפים נתונים לטבלה במהלך משימת טעינה, בוחרים באחת מהאפשרויות הבאות:

המסוף

אי אפשר לשנות את המצב של עמודה באמצעות מסוף Google Cloud .

BQ

משתמשים בפקודה bq load כדי לטעון את הנתונים, ומציינים את הדגל --noreplace כדי לציין שאתם מוסיפים את הנתונים לטבלה קיימת.

אם הנתונים שאתם מוסיפים הם בפורמט CSV או JSON עם תווי newline, ציינו את העמודות הרגועות בקובץ סכימה מקומי של JSON או השתמשו בדגל --autodetect כדי להשתמש בזיהוי סכימה כדי לגלות עמודות רגועות בנתוני המקור.

אפשר להסיק עמודות רגועות באופן אוטומטי מקובצי Avro,‏ ORC ו-Parquet. הרפיית עמודות לא חלה על פעולות append של ייצוא Datastore. העמודות בטבלאות שנוצרות על ידי טעינת קובצי ייצוא של Datastore הן תמיד NULLABLE.

מגדירים את הדגל --schema_update_option לערך ALLOW_FIELD_RELAXATION כדי לציין שהנתונים שאתם מוסיפים מכילים עמודות עם סכימה גמישה.

אם הטבלה שאתם מוסיפים נמצאת במערך נתונים בפרויקט שהוא לא פרויקט ברירת המחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

(אופציונלי) מציינים את הדגל --location ומגדירים את הערך למיקום שלכם.

מזינים את הפקודה load באופן הבא:

bq --location=LOCATION load \
--noreplace \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--source_format=FORMAT \
PROJECT_ID:DATASET.TABLE \
PATH_TO_SOURCE \
SCHEMA

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

  • ‫LOCATION: שם המיקום. הדגל --location הוא אופציונלי. לדוגמה, אם אתם משתמשים ב-BigQuery באזור טוקיו, הגדירו את הערך של הדגל ל-asia-northeast1. אפשר להגדיר ערך ברירת מחדל למיקום באמצעות הקובץ ‎.bigqueryrc.
  • ‫FORMAT:‏ NEWLINE_DELIMITED_JSON,‏ CSV,‏ PARQUET,‏ ORC או AVRO. ב-DATASTORE_BACKUP קבצים לא צריך להרפות את העמודות. העמודות בטבלאות שנוצרו מקובצי ייצוא של Datastore הן תמיד NULLABLE.
  • PROJECT_ID: מזהה הפרויקט.
  • ‫dataset הוא שם קבוצת הנתונים שמכילה את הטבלה.
  • ‫TABLE: שם הטבלה שמוסיפים.
  • ‫PATH_TO_SOURCE: URI של Cloud Storage שמוגדר באופן מלא, רשימה מופרדת בפסיקים של מזהי URI, או הנתיב לקובץ נתונים במחשב המקומי.
  • ‫SCHEMA: הנתיב לקובץ סכימה מקומי ב-JSON. האפשרות הזו משמשת רק לקובצי CSV ו-JSON. עמודות רגועות מוסקות באופן אוטומטי מקובצי Avro.

דוגמאות:

מזינים את הפקודה הבאה כדי להוסיף קובץ נתונים מקומי בפורמט Avro,‏ /tmp/mydata.avro, ל-mydataset.mytable באמצעות משימת טעינה. מכיוון שאפשר להסיק באופן אוטומטי עמודות רגועות מנתוני Avro, אין צורך לציין קובץ סכימה. ‫mydataset נמצא בפרויקט ברירת המחדל שלכם.

bq load \
    --noreplace \
    --schema_update_option=ALLOW_FIELD_RELAXATION \
    --source_format=AVRO \
    mydataset.mytable \
    /tmp/mydata.avro

מזינים את הפקודה הבאה כדי להוסיף נתונים מקובץ JSON מופרד בשורות חדשות ב-Cloud Storage ל-mydataset.mytable באמצעות משימת טעינה. הסכימה שמכילה את העמודות המורחבות נמצאת בקובץ סכימה מקומי בפורמט JSON – ‏/tmp/myschema.json. ‫mydataset נמצא בפרויקט ברירת המחדל שלכם.

bq load \
--noreplace \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--source_format=NEWLINE_DELIMITED_JSON \
mydataset.mytable \
gs://mybucket/mydata.json \
/tmp/myschema.json

מזינים את הפקודה הבאה כדי להוסיף נתונים בקובץ CSV במחשב המקומי ל-mydataset.mytable באמצעות משימת טעינה. הפקודה משתמשת בזיהוי אוטומטי של סכימה כדי לגלות עמודות רגועות בנתוני המקור. ‫mydataset נמצא ב-myotherproject, ולא בפרויקט שמוגדר כברירת מחדל.

bq load \
--noreplace \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--source_format=CSV \
--autodetect \
myotherproject:mydataset.mytable \
mydata.csv

API

מבצעים קריאה ל-method‏ jobs.insert. מגדירים משימה ב-load ומגדירים את המאפיינים הבאים:

  • מפנים לנתונים ב-Cloud Storage באמצעות המאפיין sourceUris.
  • מציינים את פורמט הנתונים על ידי הגדרת המאפיין sourceFormat.
  • מציינים את הסכימה במאפיין schema.
  • מציינים את אפשרות עדכון הסכימה באמצעות המאפיין schemaUpdateOptions.
  • מגדירים את מאפיין הכתיבה של טבלת היעד לערך WRITE_APPEND באמצעות המאפיין writeDisposition.

המשך

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"
	"os"

	"cloud.google.com/go/bigquery"
)

// relaxTableImport demonstrates amending the schema of a table to relax columns from
// not allowing NULL values to allowing them.
func relaxTableImport(projectID, datasetID, tableID, filename string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType, Required: true},
		{Name: "age", Type: bigquery.IntegerFieldType, Required: true},
	}
	meta := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, meta); err != nil {
		return err
	}
	// Now, import data from a local file, but specify relaxation of required
	// fields as a side effect while the data is appended.
	f, err := os.Open(filename)
	if err != nil {
		return err
	}
	source := bigquery.NewReaderSource(f)
	source.AutoDetect = true   // Allow BigQuery to determine schema.
	source.SkipLeadingRows = 1 // CSV has a single header line.

	loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(source)
	loader.SchemaUpdateOptions = []string{"ALLOW_FIELD_RELAXATION"}
	job, err := loader.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}
	if err := status.Err(); err != nil {
		return err
	}
	return nil
}

Java

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.CsvOptions;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.Table;
import com.google.cloud.bigquery.TableId;
import com.google.common.collect.ImmutableList;

// Sample to append relax column in a table.
public class RelaxColumnLoadAppend {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String sourceUri = "gs://cloud-samples-data/bigquery/us-states/us-states.csv";
    relaxColumnLoadAppend(datasetName, tableName, sourceUri);
  }

  public static void relaxColumnLoadAppend(String datasetName, String tableName, String sourceUri) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      // Retrieve destination table reference
      Table table = bigquery.getTable(TableId.of(datasetName, tableName));

      // column as a 'REQUIRED' field.
      Field name =
          Field.newBuilder("name", StandardSQLTypeName.STRING).setMode(Field.Mode.REQUIRED).build();
      Field postAbbr =
          Field.newBuilder("post_abbr", StandardSQLTypeName.STRING)
              .setMode(Field.Mode.REQUIRED)
              .build();
      Schema schema = Schema.of(name, postAbbr);

      // Skip header row in the file.
      CsvOptions csvOptions = CsvOptions.newBuilder().setSkipLeadingRows(1).build();

      // Set job options
      LoadJobConfiguration loadConfig =
          LoadJobConfiguration.newBuilder(table.getTableId(), sourceUri)
              .setSchema(schema)
              .setFormatOptions(csvOptions)
              .setSchemaUpdateOptions(
                  ImmutableList.of(JobInfo.SchemaUpdateOption.ALLOW_FIELD_RELAXATION))
              .setWriteDisposition(JobInfo.WriteDisposition.WRITE_APPEND)
              .build();

      // Create a load job and wait for it to complete.
      Job job = bigquery.create(JobInfo.of(loadConfig));
      job = job.waitFor();
      // Check the job's status for errors
      if (job.isDone() && job.getStatus().getError() == null) {
        System.out.println("Relax column append successfully loaded in a table");
      } else {
        System.out.println(
            "BigQuery was unable to load into the table due to an error:"
                + job.getStatus().getError());
      }
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Column not added during load append \n" + e.toString());
    }
  }
}

Node.js

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במדריך למתחילים של BigQuery באמצעות ספריות לקוח. למידע נוסף, קראו את מאמרי העזרה של BigQuery Node.js API.

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

// Import the Google Cloud client libraries
const {BigQuery} = require('@google-cloud/bigquery');

// Instantiate client
const bigquery = new BigQuery();

async function relaxColumnLoadAppend() {
  // Changes required column to nullable in load append job.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const fileName = '/path/to/file.csv';
  // const datasetId = 'my_dataset';
  // const tableId = 'my_table';

  // In this example, the existing table contains the 'Name'
  // column as a 'REQUIRED' field.
  const schema = 'Age:INTEGER, Weight:FLOAT, IsMagic:BOOLEAN';

  // Retrieve destination table reference
  const [table] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .get();
  const destinationTableRef = table.metadata.tableReference;

  // Set load job options
  const options = {
    schema: schema,
    schemaUpdateOptions: ['ALLOW_FIELD_RELAXATION'],
    writeDisposition: 'WRITE_APPEND',
    destinationTable: destinationTableRef,
  };

  // Load data from a local file into the table
  const [job] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .load(fileName, options);

  console.log(`Job ${job.id} completed.`);

  // Check the job's status for errors
  const errors = job.status.errors;
  if (errors && errors.length > 0) {
    throw errors;
  }
}

Python

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

# from google.cloud import bigquery
# client = bigquery.Client()
# project = client.project
# dataset_ref = bigquery.DatasetReference(project, 'my_dataset')
# filepath = 'path/to/your_file.csv'

# Retrieves the destination table and checks the number of required fields
table_id = "my_table"
table_ref = dataset_ref.table(table_id)
table = client.get_table(table_ref)
original_required_fields = sum(field.mode == "REQUIRED" for field in table.schema)
# In this example, the existing table has 3 required fields.
print("{} fields in the schema are required.".format(original_required_fields))

# Configures the load job to append the data to a destination table,
# allowing field relaxation
job_config = bigquery.LoadJobConfig()
job_config.write_disposition = bigquery.WriteDisposition.WRITE_APPEND
job_config.schema_update_options = [
    bigquery.SchemaUpdateOption.ALLOW_FIELD_RELAXATION
]
# In this example, the existing table contains three required fields
# ('full_name', 'age', and 'favorite_color'), while the data to load
# contains only the first two fields.
job_config.schema = [
    bigquery.SchemaField("full_name", "STRING", mode="REQUIRED"),
    bigquery.SchemaField("age", "INTEGER", mode="REQUIRED"),
]
job_config.source_format = bigquery.SourceFormat.CSV
job_config.skip_leading_rows = 1

with open(filepath, "rb") as source_file:
    job = client.load_table_from_file(
        source_file,
        table_ref,
        location="US",  # Must match the destination dataset location.
        job_config=job_config,
    )  # API request

job.result()  # Waits for table load to complete.
print(
    "Loaded {} rows into {}:{}.".format(
        job.output_rows, dataset_id, table_ref.table_id
    )
)

# Checks the updated number of required fields
table = client.get_table(table)
current_required_fields = sum(field.mode == "REQUIRED" for field in table.schema)
print("{} fields in the schema are now required.".format(current_required_fields))

הפיכת כל העמודות ל-NULLABLE באמצעות משימת הוספה

כשמוסיפים תוצאות של שאילתה לטבלה, אפשר להגמיש את כל העמודות בטבלה. אפשר להגמיש את כל שדות החובה בטבלת היעד על ידי הגדרת הדגל --schema_update_option לערך ALLOW_FIELD_RELAXATION. אי אפשר להקל על עמודות ספציפיות בטבלת היעד באמצעות הוספת שאילתה. כדי להגמיש עמודות ספציפיות באמצעות משימת טעינה מסוג append, קראו את המאמר הפיכת עמודה ל-NULLABLE באמצעות משימת append.

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

המסוף

אי אפשר לשנות את המצב של עמודה באמצעות מסוף Google Cloud .

BQ

משתמשים בפקודה bq query כדי לשלוח שאילתה על הנתונים, ומציינים את הדגל --destination_table כדי לציין לאיזו טבלה אתם מוסיפים את הנתונים.

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

מגדירים את הדגל --schema_update_option לערך ALLOW_FIELD_RELAXATION כדי לציין שצריך לשנות את כל העמודות מסוג REQUIRED בטבלה שמוסיפים ל-NULLABLE.

מציינים את הדגל use_legacy_sql=false כדי להשתמש בתחביר GoogleSQL לשאילתה.

אם הטבלה שאתם מוסיפים נמצאת במערך נתונים בפרויקט שהוא לא פרויקט ברירת המחדל, הוסיפו את מזהה הפרויקט לשם של מערך הנתונים בפורמט הבא: PROJECT_ID:DATASET.

(אופציונלי) מציינים את הדגל --location ומגדירים את הערך למיקום שלכם.

bq --location=LOCATION query \
--destination_table PROJECT_ID:DATASET.TABLE \
--append_table \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--use_legacy_sql=false \
'QUERY'

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

  • ‫LOCATION: שם המיקום. הדגל --location הוא אופציונלי. לדוגמה, אם אתם משתמשים ב-BigQuery באזור טוקיו, הגדירו את הערך של הדגל ל-asia-northeast1. אפשר להגדיר ערך ברירת מחדל למיקום באמצעות הקובץ ‎.bigqueryrc.
  • PROJECT_ID: מזהה הפרויקט.
  • ‫DATASET: שם קבוצת הנתונים שמכילה את הטבלה שמוסיפים.
  • ‫TABLE: שם הטבלה שמוסיפים.
  • ‫QUERY: שאילתה בתחביר GoogleSQL.

דוגמאות:

מזינים את שאילתת הפקודה הבאה mydataset.mytable בפרויקט ברירת המחדל כדי להוסיף את תוצאות השאילתה ל-mydataset.mytable2 (גם בפרויקט ברירת המחדל). הפקודה משנה את כל העמודות מסוג REQUIRED בטבלת היעד ל-NULLABLE.

bq query \
    --destination_table mydataset.mytable2 \
    --append_table \
    --schema_update_option=ALLOW_FIELD_RELAXATION \
    --use_legacy_sql=false \
    'SELECT
       column1,column2
     FROM
       mydataset.mytable'

מזינים את שאילתת הפקודה הבאה, mydataset.mytable, בפרויקט ברירת המחדל, כדי להוסיף את תוצאות השאילתה ל-mydataset.mytable2 ב-myotherproject. הפקודה משנה את כל העמודות מסוג REQUIRED בטבלת היעד ל-NULLABLE.

bq query \
--destination_table myotherproject:mydataset.mytable2 \
--append_table \
--schema_update_option=ALLOW_FIELD_RELAXATION \
--use_legacy_sql=false \
'SELECT
   column1,column2
 FROM
   mydataset.mytable'

API

מבצעים קריאה ל-method‏ jobs.insert. מגדירים משימה ב-query ומגדירים את המאפיינים הבאים:

  • מציינים את טבלת היעד באמצעות המאפיין destinationTable.
  • מגדירים את מאפיין הכתיבה של טבלת היעד לערך WRITE_APPEND באמצעות המאפיין writeDisposition.
  • מציינים את אפשרות עדכון הסכימה באמצעות המאפיין schemaUpdateOptions.
  • מציינים את שאילתת GoogleSQL באמצעות המאפיין query.

המשך

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// relaxTableQuery demonstrates relaxing the schema of a table by appending query results to
// enable the table to allow NULL values.
func relaxTableQuery(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	sampleSchema := bigquery.Schema{
		{Name: "full_name", Type: bigquery.StringFieldType, Required: true},
		{Name: "age", Type: bigquery.IntegerFieldType, Required: true},
	}
	meta := &bigquery.TableMetadata{
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, meta); err != nil {
		return err
	}
	// Now, append a query result that includes nulls, but allow the job to relax
	// all required columns.
	q := client.Query("SELECT \"Beyonce\" as full_name")
	q.QueryConfig.Dst = client.Dataset(datasetID).Table(tableID)
	q.SchemaUpdateOptions = []string{"ALLOW_FIELD_RELAXATION"}
	q.WriteDisposition = bigquery.WriteAppend
	q.Location = "US"
	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	_, err = job.Wait(ctx)
	if err != nil {
		return err
	}
	return nil
}

Java

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobInfo.SchemaUpdateOption;
import com.google.cloud.bigquery.JobInfo.WriteDisposition;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableResult;
import com.google.common.collect.ImmutableList;

public class RelaxTableQuery {

  public static void runRelaxTableQuery() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    relaxTableQuery(projectId, datasetName, tableName);
  }

  // To relax all columns in a destination table when you append data to it during a query job
  public static void relaxTableQuery(String projectId, String datasetName, String tableName)
      throws Exception {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);

      String sourceTable = "`" + projectId + "." + datasetName + "." + tableName + "`";
      String query = "SELECT word FROM " + sourceTable + " WHERE word like '%is%'";

      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              // Use standard SQL syntax for queries.
              // See: https://cloud.google.com/bigquery/sql-reference/
              .setUseLegacySql(false)
              .setSchemaUpdateOptions(ImmutableList.of(SchemaUpdateOption.ALLOW_FIELD_RELAXATION))
              .setWriteDisposition(WriteDisposition.WRITE_APPEND)
              .setDestinationTable(tableId)
              .build();

      Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).build());

      queryJob = queryJob.waitFor();

      // Check for errors
      if (queryJob == null) {
        throw new Exception("Job no longer exists");
      } else if (queryJob.getStatus().getError() != null) {
        // You can also look at queryJob.getStatus().getExecutionErrors() for all
        // errors, not just the latest one.
        throw new Exception(queryJob.getStatus().getError().toString());
      }

      // Get the results.
      TableResult results = queryJob.getQueryResults();

      // Print all pages of the results.
      results
          .iterateAll()
          .forEach(
              rows -> {
                rows.forEach(row -> System.out.println("row: " + row.toString()));
              });

      System.out.println("Successfully relaxed all columns in destination table during query job");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Columns not relaxed during query job \n" + e.toString());
    }
  }
}

Python

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

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the destination table.
# table_id = "your-project.your_dataset.your_table_name"

# Retrieves the destination table and checks the number of required fields.
table = client.get_table(table_id)  # Make an API request.
original_required_fields = sum(field.mode == "REQUIRED" for field in table.schema)

# In this example, the existing table has 2 required fields.
print("{} fields in the schema are required.".format(original_required_fields))

# Configures the query to append the results to a destination table,
# allowing field relaxation.
job_config = bigquery.QueryJobConfig(
    destination=table_id,
    schema_update_options=[bigquery.SchemaUpdateOption.ALLOW_FIELD_RELAXATION],
    write_disposition=bigquery.WriteDisposition.WRITE_APPEND,
)

# Start the query, passing in the extra configuration.
client.query_and_wait(
    # In this example, the existing table contains 'full_name' and 'age' as
    # required columns, but the query results will omit the second column.
    'SELECT "Beyonce" as full_name;',
    job_config=job_config,
)  # Make an API request and wait for job to complete

# Checks the updated number of required fields.
table = client.get_table(table_id)  # Make an API request.
current_required_fields = sum(field.mode == "REQUIRED" for field in table.schema)
print("{} fields in the schema are now required.".format(current_required_fields))

שינוי ערך ברירת המחדל של עמודה

כדי לשנות את ערך ברירת המחדל של עמודה, בוחרים באחת מהאפשרויות הבאות:

המסוף

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בחלונית הימנית, לוחצים על Explorer:

    כפתור מודגש לחלונית Explorer.

    אם החלונית הימנית לא מוצגת, לוחצים על הרחבת החלונית הימנית כדי לפתוח אותה.

  3. בחלונית Explorer, מרחיבים את הפרויקט, לוחצים על Datasets ובוחרים את מערך הנתונים.

  4. לוחצים על סקירה כללית > טבלאות, ואז לוחצים על טבלה.

  5. בחלונית הפרטים, לוחצים על Edit > Edit schema.

  6. בדף Current schema, מאתרים את השדה ברמה העליונה שרוצים לשנות.

  7. מזינים את ערך ברירת המחדל של השדה הזה.

  8. לוחצים על Save.

SQL

משתמשים בהצהרת ה-DDL‏ ALTER COLUMN SET DEFAULT.

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בעורך השאילתות, מזינים את ההצהרה הבאה:

    ALTER TABLE mydataset.mytable
    ALTER COLUMN column_name SET DEFAULT default_expression;

  3. ‫לוחצים על Run.

מידע נוסף על הרצת שאילתות זמין במאמר הרצת שאילתה אינטראקטיבית.

שינוי תיאור של עמודה

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

המסוף

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בחלונית הימנית, לוחצים על Explorer:

    כפתור מודגש לחלונית Explorer.

  3. בחלונית Explorer, מרחיבים את הפרויקט, לוחצים על Datasets ובוחרים קבוצת נתונים.

  4. לוחצים על סקירה כללית > טבלאות, ובוחרים את הטבלה.

  5. בחלונית הפרטים, לוחצים על Edit > Edit schema.

  6. בדף Current schema, מאתרים את השדה שרוצים לשנות.

  7. מזינים את התיאור של השדה הזה.

  8. לוחצים על Save.

SQL

משתמשים בהצהרת ה-DDL‏ ALTER COLUMN SET OPTIONS.

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בעורך השאילתות, מזינים את ההצהרה הבאה:

    ALTER TABLE mydataset.mytable
    ALTER COLUMN column_name
    SET OPTIONS (description = 'This is a column description.');

  3. ‫לוחצים על Run.

מידע נוסף על הרצת שאילתות זמין במאמר הרצת שאילתה אינטראקטיבית.

Gemini

אתם יכולים ליצור תיאורי עמודות באמצעות Gemini ב-BigQuery על סמך תובנות מנתונים. תובנות מנתונים הן דרך אוטומטית לחקור, להבין ולנהל את הנתונים.

במאמר יצירת תובנות מנתונים ב-BigQuery מוסבר בהרחבה על תובנות מנתונים, כולל שלבי ההגדרה, תפקידי ה-IAM הנדרשים ושיטות מומלצות לשיפור הדיוק של התובנות שנוצרו על ידי AI.

  1. נכנסים לדף BigQuery במסוף Google Cloud .

    כניסה ל-BigQuery

  2. בחלונית הימנית, לוחצים על Explorer:

    כפתור מודגש לחלונית Explorer.

  3. בחלונית Explorer, מרחיבים את הפרויקט ואת מערך הנתונים ובוחרים את הטבלה.

  4. בחלונית הפרטים, לוחצים על הכרטיסייה פרטים.

  5. ליד פרטי הטבלה, לוחצים על תיאור הנתונים.

    ‫Gemini יוצר תיאורים של העמודות ותובנות לגבי הטבלה. המידע יופיע תוך כמה דקות. ניתן להציג את התובנות שנוצרו על ידי AI בכרטיסייה Insights של הטבלה.

  6. כדי לערוך ולשמור את תיאורי העמודות שנוצרו, מבצעים את הפעולות הבאות:

    1. לצד פרטי הטבלה, לוחצים על הצגת התיאורים.

    2. בקטע Column descriptions, לוחצים על Save to schema.

      תיאורי העמודות שנוצרו מאוכלסים בשדה New description של כל עמודה.

    3. עורכים את תיאורי העמודות לפי הצורך ולוחצים על שמירה.

      תיאורי העמודות מתעדכנים באופן מיידי.

    4. כדי לסגור את החלונית Preview descriptions, לוחצים על Close.

מחיקת עמודה

כדי למחוק עמודה מטבלה קיימת, משתמשים בהצהרת ה-DDL‏ ALTER TABLE DROP COLUMN.

ההצהרה לא מפנה באופן מיידי את האחסון שמשויך לעמודה שהוסרה. כדי לקרוא מידע נוסף על ההשפעה על האחסון כשמורידים עמודה באחסון, קראו את פרטי ההצהרה ALTER TABLE DROP COLUMN. יש שתי אפשרויות לפנות מקום באחסון באופן מיידי:

  • החלפת טבלה באמצעות שאילתת SELECT * EXCEPT:

    CREATE OR REPLACE TABLE mydataset.mytable AS (
      SELECT * EXCEPT (column_to_delete) FROM mydataset.mytable
    );
    
  • לייצא את הנתונים ל-Cloud Storage, למחוק את העמודות הלא רצויות ואז לטעון את הנתונים לטבלה חדשה עם הסכימה הנכונה.

עדכוני סכימה לא יכולים להשמיט שדות בתצוגת עץ.