스키마 자동 감지 사용

스키마 자동 감지

BigQuery로 데이터를 로드하거나 외부 데이터 소스를 쿼리할 때 스키마 자동 감지를 사용할 수 있습니다.

자동 감지를 사용 설정하면 BigQuery가 데이터 소스에서 무작위로 파일을 선택하고 데이터 행을 최대 100개까지 검사하여 대표 샘플로 사용되는 추론 프로세스를 시작합니다. 그러면 BigQuery는 각 필드를 검사하고 샘플 값을 기준으로 필드에 데이터 유형을 할당합니다.

테이블에 대해 감지된 스키마는 다음과 같은 방법으로 표시됩니다.

  • Cloud Console 사용
  • bq 명령줄 도구의 bq show 명령어 사용

BigQuery에서 스키마를 감지하면 드물지만 필드 이름을 BigQuery SQL 구문과 호환되도록 변경할 수 있습니다.

데이터 유형 변환에 대한 자세한 내용은 다음 페이지를 참조하세요.

스키마 자동 감지를 사용하여 데이터 로드

데이터 로드 시 스키마 자동 감지를 사용 설정하려면 다음 접근 방법 중 하나를 사용합니다.

  • Cloud Console의 스키마 섹션에서 자동 감지에 대해스키마 및 입력 매개변수 옵션을 선택합니다.
  • bq 명령줄 도구에서 --autodetect 매개변수와 함께 bq load 명령어를 사용합니다.

스키마 자동 감지가 사용 설정되면 BigQuery가 CSV 및 JSON 파일의 스키마를 자동으로 추론하려고 합니다.

Avro 파일, Parquet 파일, ORC 파일, Firestore 내보내기 파일 또는 Datastore 내보내기 파일에는 스키마 자동 감지를 사용할 수 없습니다. 이러한 파일을 BigQuery로 로드하면 테이블 스키마가 자체 설명적 소스 데이터에서 자동으로 검색됩니다.

JSON 또는 CSV 데이터를 로드할 때 스키마 자동 감지를 사용하려면 다음 안내를 따르세요.

Console

  1. Cloud Console에서 BigQuery 페이지로 이동합니다.

    BigQuery로 이동

  2. 탐색기 패널에서 프로젝트를 확장하고 데이터 세트를 선택합니다.

  3. 세부정보 패널에서 테이블 만들기를 클릭합니다.

  4. 테이블 만들기 페이지의 소스 섹션에서 다음을 수행합니다.

    • 다음 항목으로 테이블 만들기에서 원하는 소스 유형을 선택합니다.
    • 소스 필드에서 파일/Cloud Storage 버킷을 찾거나 Cloud Storage URI를 입력합니다. Cloud Console에서는 URI를 여러 개 포함할 수 없지만 와일드 카드는 지원됩니다. Cloud Storage 버킷은 만들려는 테이블이 포함된 데이터 세트와 같은 위치에 있어야 합니다.

      파일 선택

    • 파일 형식의 경우 CSV 또는 JSON을 선택합니다.

  5. 테이블 만들기 페이지의 대상 섹션에서 다음을 수행합니다.

    • 데이터 세트 이름에서 적절한 데이터 세트를 선택합니다.

      데이터 세트 선택

    • 테이블 이름 필드에 생성할 테이블의 이름을 입력합니다.

    • 테이블 유형기본 테이블로 설정되어 있는지 확인합니다.

  6. 테이블 만들기를 클릭합니다.

bq

bq load 명령어를 --autodetect 매개변수와 함께 실행합니다.

(선택사항) --location 플래그를 지정하고 값을 사용자 위치로 설정합니다.

다음 명령어는 스키마 자동 감지를 사용하여 파일을 로드합니다.

bq --location=LOCATION load \
--autodetect \
--source_format=FORMAT \
DATASET.TABLE \
PATH_TO_SOURCE

다음을 바꿉니다.

  • LOCATION: 위치의 이름입니다. --location 플래그는 선택사항입니다. 예를 들어 도쿄 리전에서 BigQuery를 사용하는 경우 플래그 값을 asia-northeast1로 설정합니다. .bigqueryrc 파일을 사용하여 위치 기본값을 설정할 수 있습니다.
  • FORMAT: NEWLINE_DELIMITED_JSON 또는 CSV입니다.
  • DATASET: 데이터를 로드할 테이블이 포함된 데이터 세트입니다.
  • TABLE: 데이터를 로드할 테이블의 이름입니다.
  • PATH_TO_SOURCE는 CSV 또는 JSON 파일의 위치입니다.

예를 들면 다음과 같습니다.

다음 명령어를 입력하여 로컬 머신에서 데이터 세트 mydataset에 저장된 테이블 mytablemyfile.csv를 로드합니다.

bq load --autodetect --source_format=CSV mydataset.mytable ./myfile.csv

다음 명령어를 입력하여 로컬 머신에서 데이터 세트 mydataset에 저장된 테이블 mytablemyfile.json을 로드합니다.

bq load --autodetect --source_format=NEWLINE_DELIMITED_JSON \
mydataset.mytable ./myfile.json

API

  1. 소스 데이터를 가리키는 load 작업을 만듭니다. 작업 만들기에 대한 자세한 내용은 프로그래매틱 방식으로 BigQuery 작업 실행을 참조하세요. jobReferencelocation 속성에 위치를 지정합니다.

  2. sourceFormat 속성을 설정하여 데이터 형식을 지정합니다. 스키마 자동 감지를 사용하려면 이 값을 NEWLINE_DELIMITED_JSON 또는 CSV로 설정해야 합니다.

  3. autodetect 속성을 사용하여 스키마 자동 감지를 true로 설정합니다.

Go

이 샘플을 사용해 보기 전에 BigQuery 빠른 시작: 클라이언트 라이브러리 사용의 Go 설정 안내를 따르세요. 자세한 내용은 BigQuery Go API 참조 문서를 확인하세요.

import (
	"context"
	"fmt"

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

// importJSONAutodetectSchema demonstrates loading data from newline-delimited JSON data in Cloud Storage
// and using schema autodetection to identify the available columns.
func importJSONAutodetectSchema(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()

	gcsRef := bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/us-states/us-states.json")
	gcsRef.SourceFormat = bigquery.JSON
	gcsRef.AutoDetect = true
	loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(gcsRef)
	loader.WriteDisposition = bigquery.WriteEmpty

	job, err := loader.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}

	if status.Err() != nil {
		return fmt.Errorf("job completed with error: %v", status.Err())
	}
	return nil
}

자바

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.FormatOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.TableId;

// Sample to load JSON data with autodetect schema from Cloud Storage into a new BigQuery table
public class LoadJsonFromGCSAutodetect {

  public static void runLoadJsonFromGCSAutodetect() {
    // 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.json";
    loadJsonFromGCSAutodetect(datasetName, tableName, sourceUri);
  }

  public static void loadJsonFromGCSAutodetect(
      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();

      TableId tableId = TableId.of(datasetName, tableName);
      LoadJobConfiguration loadConfig =
          LoadJobConfiguration.newBuilder(tableId, sourceUri)
              .setFormatOptions(FormatOptions.json())
              .setAutodetect(true)
              .build();

      // Load data from a GCS JSON file into the table
      Job job = bigquery.create(JobInfo.of(loadConfig));
      // Blocks until this load table job completes its execution, either failing or succeeding.
      job = job.waitFor();
      if (job.isDone()) {
        System.out.println("Json Autodetect from GCS 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

이 샘플을 사용해 보기 전에 BigQuery 빠른 시작: 클라이언트 라이브러리 사용의 Node.js 설정 안내를 따르세요. 자세한 내용은 BigQuery Node.js API 참조 문서를 확인하세요.

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

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

/**
 * This sample loads the JSON file at
 * https://storage.googleapis.com/cloud-samples-data/bigquery/us-states/us-states.json
 *
 * TODO(developer): Replace the following lines with the path to your file.
 */
const bucketName = 'cloud-samples-data';
const filename = 'bigquery/us-states/us-states.json';

async function loadJSONFromGCSAutodetect() {
  // Imports a GCS file into a table with autodetected schema.

  // Instantiate clients
  const bigquery = new BigQuery();
  const storage = new Storage();

  // Configure the load job. For full list of options, see:
  // https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationLoad
  const metadata = {
    sourceFormat: 'NEWLINE_DELIMITED_JSON',
    autodetect: true,
    location: 'US',
  };

  // Load data from a Google Cloud Storage file into the table
  const [job] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .load(storage.bucket(bucketName).file(filename), metadata);
  // load() waits for the job to finish
  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;
  }
}
loadJSONFromGCSAutodetect();

PHP

이 샘플을 사용해 보기 전에 BigQuery 빠른 시작: 클라이언트 라이브러리 사용의 PHP 설정 안내를 따르세요. 자세한 내용은 BigQuery PHP API 참조 문서를 참조하세요.

use Google\Cloud\BigQuery\BigQueryClient;
use Google\Cloud\Core\ExponentialBackoff;

/** Uncomment and populate these variables in your code */
// $projectId  = 'The Google project ID';
// $datasetId  = 'The BigQuery dataset ID';
// $tableId    = 'us_states';

// instantiate the bigquery table service
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);

// create the import job
$gcsUri = 'gs://cloud-samples-data/bigquery/us-states/us-states.json';
$loadConfig = $table->loadFromStorage($gcsUri)->autodetect(true)->sourceFormat('NEWLINE_DELIMITED_JSON');
$job = $table->runJob($loadConfig);
// poll the job until it is complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
    print('Waiting for job to complete' . PHP_EOL);
    $job->reload();
    if (!$job->isComplete()) {
        throw new Exception('Job has not yet completed', 500);
    }
});
// check if the job has errors
if (isset($job->info()['status']['errorResult'])) {
    $error = $job->info()['status']['errorResult']['message'];
    printf('Error running job: %s' . PHP_EOL, $error);
} else {
    print('Data imported successfully' . PHP_EOL);
}

Python

스키마 자동 감지를 사용 설정하려면 LoadJobConfig.autodetect 속성을 True로 설정합니다.

이 샘플을 사용해 보기 전에 BigQuery 빠른 시작: 클라이언트 라이브러리 사용의 Python 설정 안내를 따르세요. 자세한 내용은 BigQuery Python API 참조 문서를 확인하세요.

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 create.
# table_id = "your-project.your_dataset.your_table_name

# Set the encryption key to use for the destination.
# TODO: Replace this key with a key you have created in KMS.
# kms_key_name = "projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}".format(
#     "cloud-samples-tests", "us", "test", "test"
# )
job_config = bigquery.LoadJobConfig(
    autodetect=True, source_format=bigquery.SourceFormat.NEWLINE_DELIMITED_JSON
)
uri = "gs://cloud-samples-data/bigquery/us-states/us-states.json"
load_job = client.load_table_from_uri(
    uri, table_id, job_config=job_config
)  # Make an API request.
load_job.result()  # Waits for the job to complete.
destination_table = client.get_table(table_id)
print("Loaded {} rows.".format(destination_table.num_rows))

Ruby

이 샘플을 사용해 보기 전에 BigQuery 빠른 시작: 클라이언트 라이브러리 사용의 Ruby 설정 안내를 따르세요. 자세한 내용은 BigQuery Ruby API 참조 문서를 확인하세요.

require "google/cloud/bigquery"

def load_table_gcs_json_autodetect dataset_id = "your_dataset_id"
  bigquery = Google::Cloud::Bigquery.new
  dataset  = bigquery.dataset dataset_id
  gcs_uri  = "gs://cloud-samples-data/bigquery/us-states/us-states.json"
  table_id = "us_states"

  load_job = dataset.load_job table_id,
                              gcs_uri,
                              format:     "json",
                              autodetect: true
  puts "Starting job #{load_job.job_id}"

  load_job.wait_until_done! # Waits for table load to complete.
  puts "Job finished."

  table = dataset.table table_id
  puts "Loaded #{table.rows_count} rows to table #{table.id}"
end

외부 데이터 소스의 스키마 자동 감지

스키마 자동 감지는 CSV, JSON, 스프레드시트 외부 데이터 소스와 함께 사용할 수 있습니다. 스키마 자동 감지가 사용 설정되면 BigQuery는 소스 데이터의 스키마를 자동으로 추론하려고 합니다. 이러한 소스에 스키마 자동 감지를 사용 설정하지 않으면 명시적인 스키마를 제공해야 합니다.

Avro, Parquet, ORC 형식, Firestore 내보내기 파일 또는 Datastore 내보내기 파일과 같은 자체 설명의 외부 파일에는 스키마 자동 감지를 사용할 수 없습니다. 이러한 파일 형식 중 하나에 연결된 테이블을 만들면 BigQuery가 자체 설명적 소스 데이터에서 스키마를 자동으로 검색합니다.

Cloud Console에서 자동 감지스키마 및 입력 매개변수 옵션을 확인하여 스키마 자동 감지를 사용 설정할 수 있습니다.

bq 명령줄 도구를 사용하면 CSV, JSON, Google 스프레드시트 데이터의 테이블 정의 파일을 만들 때 스키마 자동 감지를 사용 설정할 수 있습니다. bq 도구를 사용하여 테이블 정의 파일을 만드는 경우 --autodetect 플래그를 mkdef 명령어에 전달하여 스키마 자동 감지를 사용 설정하거나 --noautodetect 플래그를 전달하여 자동 감지를 사용 중지합니다.

--autodetect 플래그를 사용하면 테이블 정의 파일에서 autodetect 설정이 true로 설정됩니다. --noautodetect 플래그를 사용하면 autodetect 설정이 false로 설정됩니다. 테이블 정의를 만들 때 외부 데이터 소스에 대한 스키마 정의를 제공하지 않고 --noautodetect 또는 --autodetect 플래그를 사용하지 않는 경우 autodetect 설정의 기본값은 true로 설정됩니다.

API를 사용하여 테이블 정의 파일을 만들 때 autodetect 속성값을 true 또는 false로 설정합니다. autodetecttrue로 설정하면 자동 감지가 사용 설정됩니다. autodetectfalse로 설정하면 자동 감지가 사용 중지됩니다.

자동 감지 세부정보

자동 감지는 스키마 세부정보를 감지할 뿐만 아니라 다음을 인식합니다.

압축

BigQuery는 파일을 열 때 gzip 호환 파일 압축을 인식합니다.

CSV 구분 기호

BigQuery는 다음과 같은 구분 기호를 감지합니다.

  • 쉼표(,)
  • 파이프(|)
  • 탭(\t)

CSV 헤더

BigQuery는 파일의 첫 번째 행과 데이터 세트의 다른 행을 비교하여 헤더를 추론합니다. 첫 번째 행이 문자열만 포함하고 다른 행이 다른 데이터 유형을 포함하지 않으면, BigQuery는 첫 번째 행이 헤더 행이라고 가정합니다. 이 경우 BigQuery는 제목 행의 필드 이름을 기준으로 열 이름을 할당합니다. BigQuery의 열에 대해 이름 지정 규칙을 충족하도록 이름을 수정할 수 있습니다. 예를 들어 공백은 밑줄로 대체됩니다.

그렇지 않으면 BigQuery가 첫 번째 행을 데이터 행으로 간주하고 string_field_1과 같은 일반적인 열 이름을 할당합니다. 테이블 생성 후 이름을 수동으로 변경할 수 있더라도 테이블 생성 후에는 스키마에서 열 이름을 업데이트할 수 없습니다. 또 다른 옵션은 자동 감지를 사용하는 대신 명시적으로 스키마를 제공하는 것입니다.

모든 데이터 필드가 문자열인 제목 행이 포함된 CSV 파일을 사용할 수 있습니다. 이 경우 BigQuery는 첫 번째 행이 제목인 것을 자동으로 감지하지 못합니다. -skip_leading_rows 옵션을 사용하여 제목 행을 건너 뜁니다. 그렇지 않으면 제목을 데이터로 가져옵니다. 이 경우에도 열 이름을 할당할 수 있도록 명시적으로 스키마를 제공하는 것이 좋습니다.

CSV 따옴표 안 줄바꿈

BigQuery는 CSV 필드 내의 따옴표 안 줄바꿈 문자를 감지하지만 이를 행 경계로 해석하지 않습니다.

날짜 및 시간 값

BigQuery는 소스 데이터의 형식을 기준으로 날짜 및 시간 값을 감지합니다.

DATE 열의 값은 YYYY-MM-DD 형식이어야 합니다.

TIME 열의 값은 HH:MM:SS[.SSSSSS] 형식이어야 합니다. 소수점 이하 초 구성요소는 선택사항입니다.

TIMESTAMP 열의 경우 BigQuery가 다음을 포함하지만 이에 제한되지 않는 다양한 타임스탬프 형식의 배열을 감지합니다.

  • YYYY-MM-DD HH:MM
  • YYYY-MM-DD HH:MM:SS
  • YYYY-MM-DD HH:MM:SS.SSSSSS
  • YYYY/MM/DD HH:MM

또한 타임스탬프는 UTC 오프셋 또는 UTC 영역 지정자('Z')를 포함할 수 있습니다.

다음은 BigQuery가 타임스탬프 값으로 자동으로 감지하는 몇 가지 값 예시입니다.

  • 2018-08-19 12:11
  • 2018-08-19 12:11:35.22
  • 2018/08/19 12:11
  • 2018-08-19 07:11:35.220 -05:00

BigQuery에 형식이 인식되지 않으면 열을 문자열 데이터 유형으로 로드합니다. 이 경우에는 로드하기 전에 소스 데이터를 사전 처리해야 할 수 있습니다. 예를 들어 스프레드시트에서 CSV 데이터를 내보내는 경우, 여기에 표시된 예시 중 하나와 일치하도록 날짜 형식을 설정합니다. 또는 BigQuery로 로드한 후 데이터를 변환할 수 있습니다.

JSON 중첩 및 반복 필드

BigQuery는 JSON 파일에서 중첩 및 반복 필드를 추론합니다. 필드 값이 JSON 객체이면 BigQuery는 열을 RECORD 유형으로 로드합니다. 필드 값이 배열인 경우 BigQuery는 열을 반복 열로 로드합니다. 중첩 및 반복 데이터가 있는 JSON 데이터의 예시는 중첩 및 반복 JSON 데이터 로드를 참조하세요.