로컬 데이터 소스에서 데이터 로드

이 페이지에서는 로컬 데이터 소스에서 데이터를 로드하는 방법에 대해 설명합니다.

로컬 데이터 소스에서 데이터를 로드하는 방법에 대한 가이드는 다음을 참조하세요.

개요

다음과 같은 방법으로 읽을 수 있는 데이터 소스(예: 로컬 시스템)에서 데이터를 로드할 수 있습니다.

  • GCP Console 또는 기본 BigQuery 웹 UI 사용
  • CLI의 bq load 명령어 사용
  • API 사용
  • 클라이언트 라이브러리 사용

GCP Console, 기본 BigQuery 웹 UI, CLI를 사용하여 데이터를 로드하면 로드 작업이 자동으로 생성됩니다.

제한사항

로컬 데이터 소스에서 데이터 로드 시 다음과 같은 제한사항이 적용됩니다.

  • 로컬 데이터 소스에서 파일 로드 시 와일드 카드와 쉼표로 구분된 목록이 지원되지 않습니다. 파일을 개별적으로 로드해야 합니다.
  • 기본 BigQuery 웹 UI를 사용하는 경우 로컬 데이터 소스에서 로드되는 파일은 10MB 이하여야 하며 파일에 포함된 행은 16,000개 미만이어야 합니다.

필수 권한

BigQuery에 데이터를 로드하려면 최소한 다음 권한이 부여되어 있어야 합니다.

  • 새 테이블을 만들기 위한 bigquery.tables.create
  • 테이블을 덮어쓰거나 추가하는 경우 bigquery.tables.updateData
  • 로드 작업을 실행하기 위한 bigquery.jobs.create

사전 정의된 다음 Cloud IAM 역할에는 bigquery.tables.createbigquery.tables.updateData 권한이 모두 포함되어 있습니다.

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

사전 정의된 다음 Cloud IAM 역할에는 bigquery.jobs.create 권한이 포함되어 있습니다.

  • bigquery.user
  • bigquery.jobUser
  • bigquery.admin

또한 사용자에게 bigquery.datasets.create 권한이 있으면 해당 사용자가 데이터세트를 만들 때 이에 대한 bigquery.dataOwner 액세스 권한이 부여됩니다. bigquery.dataOwner 액세스 권한은 사용자가 데이터세트의 테이블에 데이터를 로드할 수 있게 해줍니다.

BigQuery의 Cloud IAM 역할 및 권한에 대한 자세한 내용은 액세스 제어를 참조하세요.

로컬 데이터 소스에서 데이터 로드

로컬 데이터 소스에서 데이터를 로드하려면 다음 안내를 따르세요.

Console

  1. GCP Console에서 BigQuery 웹 UI를 엽니다.
    GCP Console로 이동

  2. 탐색 패널의 리소스 섹션에서 프로젝트를 확장하고 데이터세트를 선택합니다.

  3. 창의 오른쪽에 있는 세부정보 패널에서 테이블 만들기를 클릭합니다. 데이터를 로드하는 프로세스는 빈 테이블을 만드는 프로세스와 동일합니다.

    테이블 만들기

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

    • 다음 항목으로 테이블 만들기에서 업로드를 선택합니다.

      테이블 업로드

    • 파일 선택 아래에 있는 찾아보기를 클릭합니다.

      파일 찾아보기

    • 파일을 찾은 후 열기를 클릭합니다. 로컬 파일에서는 와일드 카드와 쉼표로 구분된 목록이 지원되지 않습니다.

    • 파일 형식에서 CSV, JSON(줄바꿈으로 구분), Avro, Parquet 또는 ORC를 선택합니다.

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

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

      데이터세트 보기

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

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

  6. 스키마 섹션에 스키마 정의를 입력합니다.

    • CSV 및 JSON 파일의 경우 자동 감지 옵션을 선택하여 스키마 자동 감지를 사용 설정할 수 있습니다. 다른 지원되는 파일 유형의 경우 스키마 정보는 소스 데이터에서 자체 기술됩니다.

    • 다음과 같이 스키마 정보를 수동으로 입력하는 방법도 있습니다.

      • 텍스트로 수정을 클릭하고 테이블 스키마를 JSON 배열로 입력합니다.

      • 필드 추가를 사용하여 스키마를 수동으로 입력합니다.

  7. 고급 옵션 섹션에서 해당 항목을 선택한 후 테이블 만들기를 클릭합니다. 사용 가능한 옵션에 대한 자세한 내용은 CSV 옵션JSON 옵션을 참조하세요.

기본 UI

  1. BigQuery 웹 UI로 이동합니다.
    BigQuery 웹 UI로 이동

  2. 탐색 패널에서 마우스로 데이터세트를 가리키고 아래쪽 화살표 아이콘 아래쪽 화살표 아이콘 이미지을 클릭한 후 새 테이블 만들기를 클릭합니다. 데이터를 로드하는 프로세스는 빈 테이블을 만드는 프로세스와 동일합니다.

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

    • 위치에서 파일 업로드를 선택하고 파일 선택을 클릭해 파일을 찾은 후 열기를 클릭합니다. 로컬 파일에서는 와일드 카드와 쉼표로 구분된 목록이 지원되지 않습니다.
    • 파일 형식에서 (CSV), JSON(줄바꿈으로 구분), Avro, Parquet 또는 ORC를 선택합니다.
  4. 테이블 만들기 페이지의 대상 테이블 섹션에서 다음을 수행합니다.

    • 테이블 이름으로 적절한 데이터세트를 선택하고 테이블 이름 필드에 BigQuery에서 만들 테이블의 이름을 입력합니다.
    • 테이블 유형기본 테이블로 설정되어 있는지 확인합니다.
  5. 스키마 섹션에 스키마 정의를 입력합니다.

    • CSV 및 JSON 파일의 경우 자동 감지 옵션을 선택하여 스키마 자동 감지를 사용 설정할 수 있습니다. 다른 지원되는 파일 유형의 경우 스키마 정보는 소스 데이터에서 자체 기술됩니다.

      자동 감지 링크

    • 다음과 같이 스키마 정보를 수동으로 입력하는 방법도 있습니다.

      • 텍스트로 수정을 클릭하고 테이블 스키마를 JSON 배열로 입력합니다.

        스키마를 JSON 배열로 추가

      • 필드 추가를 사용하여 스키마를 수동으로 입력합니다.

        필드 추가를 사용하여 스키마 추가

  6. 옵션 섹션에서 관련 항목을 선택하고 테이블 만들기를 클릭합니다. 사용 가능한 옵션에 대한 자세한 내용은 CSV 옵션JSON 옵션을 참조하세요.

CLI

bq load 명령어를 사용하고 source_format을 지정하고 로컬 파일 경로를 포함시킵니다.

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

기본 프로젝트가 아닌 프로젝트의 데이터를 로드하는 경우 데이터세트에 프로젝트 ID를 project_id:dataset 형식으로 추가합니다.

bq --location=location load \
--source_format=format \
project_id:dataset.table \
path_to_source \
schema

각 항목의 의미는 다음과 같습니다.

  • location은 사용자의 위치입니다. --location 플래그는 선택사항입니다. 예를 들어 도쿄 리전에서 BigQuery를 사용하는 경우 플래그 값을 asia-northeast1로 설정합니다. .bigqueryrc 파일을 사용하여 위치 기본값을 설정할 수 있습니다.
  • formatCSV, AVRO, PARQUET, ORC, NEWLINE_DELIMITED_JSON입니다.
  • project_id는 프로젝트 ID입니다.
  • dataset는 기존 데이터세트입니다.
  • table은 데이터를 로드하는 테이블 이름입니다.
  • path_to_source는 로컬 파일 경로입니다.
  • schema는 유효한 스키마입니다. 스키마는 로컬 JSON 파일일 수도 있고 명령어의 일부로 인라인으로 입력해도 됩니다. 스키마 정의를 제공하는 대신 --autodetect 플래그를 사용해도 됩니다.

또한 BigQuery가 데이터를 파싱하는 방법을 제어할 수 있는 옵션의 플래그를 추가할 수 있습니다. 예를 들어 --skip_leading_rows 플래그를 사용하면 CSV 파일에서 헤더 행을 무시할 수 있습니다. 자세한 내용은 CSV 옵션JSON 옵션을 참조하세요.

예:

다음 명령어는 줄바꿈으로 구분된 JSON 파일(mydataset)을 로컬 머신에서 기본 프로젝트의 mydata.json에 있는 mytable이라는 테이블로 로드합니다. 스키마는 이름이 myschema.json인 로컬 스키마 파일에 정의됩니다.

    bq load \
    --source_format=NEWLINE_DELIMITED_JSON \
    mydataset.mytable \
    ./mydata.json \
    ./myschema.json

다음 명령어는 CSV 파일(mydata.csv)을 로컬 머신에서 myotherprojectmydataset에 있는 mytable이라는 테이블로 로드합니다. 스키마는 field:data_type, field:data_type 형식으로 인라인으로 정의됩니다.

    bq load \
    --source_format=CSV \
    myotherproject:mydataset.mytable \
    ./mydata.csv \
    qtr:STRING,sales:FLOAT,year:STRING

다음 명령어는 CSV 파일(mydata.csv)을 로컬 머신에서 기본 프로젝트의 mydataset에 있는 mytable이라는 테이블로 로드합니다. 스키마는 스키마 자동 감지를 통해 정의됩니다.

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

C#

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

다음 코드에서는 로컬 CSV 파일을 새로운 BigQuery 테이블에 로드하는 방법을 보여줍니다. 다른 형식의 로컬 파일을 로드하려면 UploadCsvOptions 대신 JobCreationOptions 기본 클래스에서 적절한 형식의 업데이트 옵션 클래스를 사용합니다.


using Google.Cloud.BigQuery.V2;
using System;
using System.IO;

public class BigQueryLoadFromFile
{
    public void LoadFromFile(
        string projectId = "your-project-id",
        string datasetId = "your_dataset_id",
        string tableId = "your_table_id",
        string filePath = "path/to/file.csv"
    )
    {
        BigQueryClient client = BigQueryClient.Create(projectId);
        // Create job configuration
        var uploadCsvOptions = new UploadCsvOptions()
        {
            SkipLeadingRows = 1,  // Skips the file headers
            Autodetect = true
        };
        using (FileStream stream = File.Open(filePath, FileMode.Open))
        {
            // Create and run job
            // Note that there are methods available for formats other than CSV
            BigQueryJob job = client.UploadCsv(
                datasetId, tableId, null, stream, uploadCsvOptions);
            job.PollUntilCompleted();  // Waits for the job to complete.
            // Display the number of rows uploaded
            BigQueryTable table = client.GetTable(datasetId, tableId);
            Console.WriteLine(
                $"Loaded {table.Resource.NumRows} rows to {table.FullyQualifiedId}");
        }
    }
}

Go

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

다음 코드에서는 로컬 CSV 파일을 새로운 BigQuery 테이블에 로드하는 방법을 보여줍니다. 다른 형식의 로컬 파일을 로드하려면 NewReaderSourceDataFormat 속성을 적절한 형식으로 설정합니다.

// To run this sample, you will need to create (or reuse) a context and
// an instance of the bigquery client.  For example:
// import "cloud.google.com/go/bigquery"
// ctx := context.Background()
// client, err := bigquery.NewClient(ctx, "your-project-id")
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)

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
}

자바

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

다음 코드에서는 로컬 CSV 파일을 새로운 BigQuery 테이블에 로드하는 방법을 보여줍니다. 다른 형식의 로컬 파일을 로드하려면 FormatOptions를 적절한 형식으로 설정합니다.

TableId tableId = TableId.of(datasetName, tableName);
WriteChannelConfiguration writeChannelConfiguration =
    WriteChannelConfiguration.newBuilder(tableId).setFormatOptions(FormatOptions.csv()).build();
// The location must be specified; other fields can be auto-detected.
JobId jobId = JobId.newBuilder().setLocation(location).build();
TableDataWriteChannel writer = bigquery.writer(jobId, writeChannelConfiguration);
// Write data to writer
try (OutputStream stream = Channels.newOutputStream(writer)) {
  Files.copy(csvPath, stream);
}
// Get load job
Job job = writer.getJob();
job = job.waitFor();
LoadStatistics stats = job.getStatistics();
return stats.getOutputRows();

Node.js

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

다음 코드에서는 로컬 CSV 파일을 새로운 BigQuery 테이블에 로드하는 방법을 보여줍니다. 다른 형식의 로컬 파일을 로드하려면 load 함수의 metadata 매개변수를 적절한 형식으로 설정합니다.

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

async function loadLocalFile() {
  // Imports a local file into a table.

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

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

  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;
  }
}

PHP

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

다음 코드에서는 로컬 CSV 파일을 새로운 BigQuery 테이블에 로드하는 방법을 보여줍니다. 다른 형식의 로컬 파일을 로드하려면 sourceFormat을 적절한 형식으로 설정합니다.

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    = 'The BigQuery table ID';
// $source     = 'The path to the CSV source file to import';

// instantiate the bigquery table service
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);
// create the import job
$loadConfig = $table->load(fopen($source, 'r'))->sourceFormat('CSV');

$job = $table->runJob($loadConfig);
// poll the job until it is complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
    printf('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

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

다음 코드에서는 로컬 CSV 파일을 새로운 BigQuery 테이블에 로드하는 방법을 보여줍니다. 다른 형식의 로컬 파일을 로드하려면 LoadJobConfig.source_format 속성을 적절한 형식으로 설정합니다.

# from google.cloud import bigquery
# client = bigquery.Client()
# filename = '/path/to/file.csv'
# dataset_id = 'my_dataset'
# table_id = 'my_table'

dataset_ref = client.dataset(dataset_id)
table_ref = dataset_ref.table(table_id)
job_config = bigquery.LoadJobConfig()
job_config.source_format = bigquery.SourceFormat.CSV
job_config.skip_leading_rows = 1
job_config.autodetect = True

with open(filename, "rb") as source_file:
    job = client.load_table_from_file(source_file, table_ref, job_config=job_config)

job.result()  # Waits for table load to complete.

print("Loaded {} rows into {}:{}.".format(job.output_rows, dataset_id, table_id))

Ruby

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

다음 코드에서는 로컬 CSV 파일을 새로운 BigQuery 테이블에 로드하는 방법을 보여줍니다. 다른 형식의 로컬 파일을 로드하려면 Table#load_job 메서드의 format 매개변수를 적절한 형식으로 설정합니다.

require "google/cloud/bigquery"

def load_from_file(dataset_id = "your_dataset_id",
                   file_path  = "path/to/file.csv")

  bigquery = Google::Cloud::Bigquery.new
  dataset  = bigquery.dataset dataset_id
  table_id = "new_table_id"

  # Infer the config.location based on the location of the referenced dataset.
  load_job = dataset.load_job table_id, file_path do |config|
    config.skip_leading = 1
    config.autodetect   = true
  end
  load_job.wait_until_done! # Waits for table load to complete.

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

로컬 파일을 사용한 테이블에 추가 또는 덮어쓰기

소스 파일에서 또는 쿼리 결과 추가를 통해 추가 데이터를 테이블에 로드할 수 있습니다. 데이터의 스키마가 대상 테이블 또는 파티션의 스키마와 일치하지 않는다면 추가하거나 덮어쓸 때 스키마를 업데이트하면 됩니다.

데이터를 추가할 때 스키마를 업데이트하면 BigQuery에서 다음 작업을 처리할 수 있습니다.

  • 새 필드 추가
  • REQUIRED 필드를 NULLABLE로 완화

테이블을 덮어쓰는 경우, 스키마는 항상 덮어쓰기됩니다. 테이블을 덮어쓰는 경우에는 스키마 업데이트가 제한되지 않습니다.

Console 또는 기본 BigQuery 웹 UI에서 쓰기 환경설정 옵션을 사용하면 소스 파일 또는 쿼리 결과에서 데이터를 로드할 때 수행할 작업을 지정할 수 있습니다. CLI와 API는 다음 옵션을 제공합니다.

콘솔 옵션 기본 UI 옵션 CLI 플래그 BigQuery API 속성 설명
비어 있으면 쓰기 비어 있으면 쓰기 없음 WRITE_EMPTY 테이블이 비어 있는 경우에만 데이터를 씁니다.
테이블에 추가 테이블에 추가 --noreplace 또는 --replace=false. --replace를 지정하지 않으면 기본값은 추가임 WRITE_APPEND (기본값) 데이터를 테이블 끝에 추가합니다.
테이블 덮어쓰기 테이블 덮어쓰기 --replace 또는 --replace=true WRITE_TRUNCATE 새 데이터를 쓰기 전에 테이블의 기존 데이터를 모두 지웁니다.

로컬 파일에서 CSV, JSON, Avro, Parquet 또는 ORC 데이터를 로드하고 BigQuery 테이블에 추가하거나 덮어쓰려면 다음 안내를 따르세요.

Console

  1. GCP Console에서 BigQuery 웹 UI를 엽니다.
    GCP Console로 이동

  2. 탐색 패널의 리소스 섹션에서 프로젝트를 확장하고 데이터세트를 선택합니다.

  3. 창의 오른쪽에 있는 세부정보 패널에서 테이블 만들기를 클릭합니다. 데이터를 로드하는 프로세스는 빈 테이블을 만드는 프로세스와 동일합니다.

    테이블 만들기

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

    • 다음 항목으로 테이블 만들기에서 업로드를 선택합니다.

      테이블 업로드

    • 파일 선택 아래에 있는 찾아보기를 클릭합니다.

      파일 찾아보기

    • 파일을 찾은 후 열기를 클릭합니다. 로컬 파일에서는 와일드 카드와 쉼표로 구분된 목록이 지원되지 않습니다.

    • 파일 형식에서 CSV, JSON(줄바꿈으로 구분), Avro, Parquet 또는 ORC를 선택합니다.

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

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

      데이터세트 선택

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

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

  6. 스키마 섹션에 스키마 정의를 입력합니다.

    • CSV 및 JSON 파일의 경우 자동 감지 옵션을 선택하여 스키마 자동 감지를 사용 설정할 수 있습니다. 다른 지원되는 파일 유형의 경우 스키마 정보는 소스 데이터에서 자체 기술됩니다.

    • 다음과 같이 스키마 정보를 수동으로 입력하는 방법도 있습니다.

      • 텍스트로 수정을 클릭하고 테이블 스키마를 JSON 배열로 입력합니다.

      • 필드 추가를 사용하여 스키마를 수동으로 입력합니다.

  7. 고급 옵션 섹션에서 쓰기 환경설정비어 있으면 쓰기, 테이블에 추가, 테이블 덮어쓰기를 선택합니다.

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

기본 UI

  1. 테이블 만들기 페이지의 소스 데이터 섹션에서 다음을 수행합니다.
    • 위치에서 파일 업로드를 선택하고 파일 선택을 클릭해 파일을 찾은 후 열기를 클릭합니다. 로컬 파일에서는 와일드 카드와 쉼표로 구분된 목록이 지원되지 않습니다.
    • 파일 형식에서 (CSV), JSON(줄바꿈으로 구분), Avro, Parquet 또는 ORC를 선택합니다.
  2. 테이블 만들기 페이지의 대상 테이블 섹션에서 다음을 수행합니다.
    • 테이블 이름으로 적절한 데이터세트를 선택하고 테이블 이름 필드에 추가하거나 덮어쓰는 테이블의 이름을 입력합니다.
    • 테이블 유형기본 테이블로 설정되어 있는지 확인합니다.
  3. 스키마 섹션에 스키마 정의를 입력합니다. 스키마를 업데이트하려면 새 필드를 추가하거나 필드를 REQUIRED에서 NULLABLE로 변경(완화)하면 됩니다.

    • JSON 파일의 경우 자동 감지 옵션을 선택하여 스키마 자동 감지를 사용 설정할 수 있습니다.

      자동 감지 링크

    • 다음과 같이 스키마 정보를 수동으로 입력하는 방법도 있습니다.

      • 텍스트로 수정을 클릭하고 테이블 스키마를 JSON 배열로 입력합니다.

        스키마를 JSON 배열로 추가

      • 필드 추가를 사용하여 스키마를 수동으로 입력합니다.

        필드 추가를 사용하여 스키마 추가

  4. 옵션 섹션의 쓰기 환경설정에서 비어 있으면 쓰기, 테이블에 추가, 테이블 덮어쓰기를 선택합니다.

    필드 추가를 사용하여 스키마 추가

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

CLI

--replace 플래그와 함께 bq load 명령어를 입력하여 테이블을 덮어씁니다. --noreplace 플래그를 사용하여 데이터를 테이블에 추가합니다. 플래그를 지정하지 않으면 데이터 추가가 기본값입니다.

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

데이터를 추가하거나 덮어쓸 때 --schema_update_option 플래그를 이용해 새 데이터의 스키마로 대상 테이블의 스키마를 업데이트할 수 있습니다. 다음 옵션을 --schema_update_option 플래그와 함께 사용할 수 있습니다.

  • ALLOW_FIELD_ADDITION: 새 필드를 스키마에 추가합니다. 새 필드는 REQUIRED가 될 수는 없습니다.
  • ALLOW_FIELD_RELAXATION: 필수 입력란을 nullable로 완화합니다. 값 목록을 지정하려면 이 옵션을 반복하세요.
bq --location=location load \
--[no]replace \
dataset.table \
path_to_source \
schema

각 항목의 의미는 다음과 같습니다.

  • location은 사용자의 위치입니다. --location 플래그는 선택사항입니다. 예를 들어 도쿄 리전에서 BigQuery를 사용하는 경우 플래그 값을 asia-northeast1로 설정합니다. .bigqueryrc 파일을 사용하여 위치 기본값을 설정할 수 있습니다.
  • dataset는 기존 데이터세트입니다.
  • table은 데이터를 로드하는 테이블 이름입니다.
  • path_to_source는 로컬 파일 경로입니다. 로컬 파일에서는 와일드 카드와 쉼표로 구분된 목록이 지원되지 않습니다.
  • schema는 유효한 스키마입니다. 스키마는 로컬 JSON 파일일 수도 있고 명령어의 일부로 인라인으로 입력해도 됩니다. 스키마 정의를 제공하는 대신 --autodetect 플래그를 사용해도 됩니다.

또한 BigQuery가 데이터를 파싱하는 방법을 제어할 수 있는 JSON 옵션CSV 옵션의 플래그를 추가할 수 있습니다.

예:

다음 명령어는 mydata.json에서 데이터를 로드하여 mydataset에 있는 mytable이라는 테이블을 덮어씁니다. 스키마는 스키마 자동 감지를 통해 정의됩니다.

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

다음 명령어는 mydata.json에서 데이터를 로드하고 mydataset에 있는 mytable이라는 테이블에 데이터를 추가합니다. 스키마는 JSON 스키마 파일 myschema.json을 사용하여 정의됩니다.

    bq load \
    --autodetect \
    --noreplace \
    --source_format=NEWLINE_DELIMITED_JSON \
    mydataset.mytable \
    ./mydata.json \
    ./myschema.json

다음 명령어는 mydata.json에서 데이터를 로드하고 mydataset에 있는 mytable이라는 테이블에 데이터를 추가합니다. myschema.json이라는 로컬 JSON 스키마 파일이 사용됩니다. 스키마 정의에는 대상 테이블에 없는 새로운 필드가 포함됩니다.

    bq load \
    --noreplace \
    --schema_update_option=ALLOW_FIELD_ADDITION \
    --source_format=NEWLINE_DELIMITED_JSON \
    mydataset.mytable \
    ./mydata.json \
    ./myschema.json

다음 명령어는 mydata.csv에서 데이터를 로드하고 mydataset에 있는 mytable이라는 테이블에 데이터를 추가합니다. myschema.json이라는 로컬 JSON 스키마 파일이 사용됩니다. 스키마 정의는 두 개의 REQUIRED 필드를 NULLABLE로 변경(완화)합니다.

    bq load \
    --noreplace \
    --schema_update_option=ALLOW_FIELD_RELAXATION \
    --source_format=NEWLINE_DELIMITED_JSON \
    mydataset.mytable \
    ./mydata.csv \
    ./myschema.json

API 업로드

미디어 업로드 기능을 사용하면 Google BigQuery API는 데이터를 클라우드에 저장하고 서버에서 사용할 수 있습니다. 업로드할 수 있는 데이터 종류에는 사진, 동영상, PDF 파일, ZIP 파일 또는 기타 유형의 데이터가 있습니다.

업로드 옵션

Google BigQuery API를 사용하면 특정 유형의 바이너리 데이터 또는 미디어를 업로드할 수 있습니다. 업로드할 수 있는 데이터의 구체적인 특성은 미디어 업로드를 지원하는 메서드의 참조 페이지에 지정되어 있습니다.

  • 최대 업로드 파일 크기: 이 메서드로 저장할 수 있는 최대 데이터 양입니다.
  • 허용되는 미디어 MIME 유형: 이 메서드로 저장할 수 있는 바이너리 데이터 유형입니다.

업로드 요청은 다음과 같은 방법으로 가능합니다. uploadType 요청 매개변수로 사용할 메서드를 지정합니다.

  • 멀티 파트 업로드: uploadType=multipart. 작은 파일과 메타데이터를 신속하게 전송할 수 있습니다. 단일 요청으로 파일을 설명하는 메타데이터와 함께 파일을 전송합니다.
  • 재개 가능한 업로드: uploadType=resumable. 용량이 큰 파일에서 특히 중요한 안정적인 전송이 가능합니다. 이 메서드를 통해 메타데이터를 선택적으로 포함할 수 있는 세션 시작 요청을 사용할 수 있습니다. 업로드당 하나의 추가 HTTP 요청을 대가로 작은 파일에서도 작동하므로 대부분의 애플리케이션에서 사용할 수 있는 효과적인 전략입니다.

미디어를 업로드할 때는 특수 URI를 사용합니다. 사실 미디어 업로드를 지원하는 메서드에는 두 개의 URI 엔드포인트가 있습니다.

  • 미디어용 /upload URI. 업로드 엔드포인트 형식은 '/upload' 프리픽스가 포함된 표준 리소스 URI입니다. 미디어 데이터 자체를 전송할 때 이 URI를 사용합니다. 예: POST /upload/bigquery/v2/projects/projectId/jobs.
  • 메타데이터용 표준 리소스 URI. 리소스에 데이터 필드가 포함된 경우 업로드된 파일을 설명하는 메타데이터를 저장하는 데 사용됩니다. 메타데이터 값을 만들거나 업데이트할 때 이 URI를 사용할 수 있습니다. 예: POST /bigquery/v2/projects/projectId/jobs.

멀티 파트 업로드

업로드할 데이터와 함께 메타데이터를 전송하려는 경우, 한 번만 multipart/related 요청을 전송하면 됩니다. 전송할 데이터가 연결 실패 시 전체를 다시 업로드해도 될 만큼 작은 경우에 효과적인 방법입니다.

멀티 파트 업로드를 사용하려면 메서드의 /upload URI에 POST 요청을 전송하고 쿼리 매개변수 uploadType=multipart를 추가합니다. 예를 들면 다음과 같습니다.

POST https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=multipart

다중 파트 업로드 요청을 전송할 때 사용하는 최상위 HTTP 헤더에는 다음 항목이 포함됩니다.

  • Content-Type. multipart/related로 설정하고 요청에서 관련 파트를 식별하는 데 사용되는 경계 문자열을 포함합니다.
  • Content-Length. 요청 본문의 총 바이트 수로 설정합니다. 요청의 미디어 부분이 이 메소드에 지정된 최대 파일 크기보다 작아야 합니다.

요청 본문 형식은 multipart/related 콘텐츠 유형 [RFC2387]이며 정확히 두 파트로 구성됩니다. 파트는 경계 문자열로 식별되며 최종 경계 문자열 뒤에는 하이픈 두 개가 있습니다.

다중 파트 요청의 각 파트에는 추가 Content-Type 헤더가 필요합니다.

  1. 메타데이터 파트: 첫 번째 위치에 있어야 하며 Content-Type은 허용되는 메타데이터 형식 중 하나와 일치해야 합니다.
  2. 미디어 파트: 두 번째 위치에 있어야 하며 Content-Type은 메서드에서 허용되는 미디어 MIME 유형과 일치해야 합니다.

파일 업로드와 관련된 각 메서드에서 허용되는 미디어 MIME 유형 및 크기 제한 목록은 API 참조를 확인하세요.

참고: 관련 데이터를 업로드하지 않고 메타데이터 부분만 만들거나 업데이트하려면 POST 또는 PUT 요청을 표준 리소스 엔드포인트(https://www.googleapis.com/bigquery/v2/projects/projectId/jobs)에 전송하면 됩니다.

예: 멀티 파트 업로드

아래 예에서는 Google BigQuery API의 다중 파트 업로드 요청을 보여줍니다.

POST /upload/bigquery/v2/projects/projectId/jobs?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Type: multipart/related; boundary=foo_bar_baz
Content-Length: number_of_bytes_in_entire_request_body

--foo_bar_baz
Content-Type: application/json; charset=UTF-8

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}

--foo_bar_baz
Content-Type: */*

CSV, JSON, AVRO, PARQUET, or ORC data
--foo_bar_baz--

요청이 성공하면 서버에서 HTTP 200 OK 상태 코드와 메타데이터를 반환합니다.

HTTP/1.1 200
Content-Type: application/json

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}

재개 가능한 업로드

데이터 파일을 보다 안정적으로 업로드하려면 재개 가능한 업로드 프로토콜을 사용하면 됩니다. 이 프로토콜을 사용하면 통신 실패로 데이터 흐름이 중단된 경우 이후 업로드 작업을 재개할 수 있습니다. 큰 파일을 전송하거나 모바일 클라이언트 앱에서 업로드하는 등 네트워크 중단 또는 기타 전송 실패가 발생할 가능성이 높을 때 특히 유용합니다. 대용량 파일을 처음부터 다시 업로드할 필요가 없으므로 네트워크 실패 시 대역폭 사용량도 줄일 수 있습니다.

재개 가능한 업로드의 단계는 다음과 같습니다.

  1. 재개 가능한 세션 시작. 시작 요청을 메타데이터(있는 경우)가 포함된 업로드 URI에 전송합니다.
  2. 재개 가능한 세션 URI 저장. 시작 요청 응답에서 반환된 세션 URI를 저장합니다. 이 URI는 이 세션의 나머지 요청에 사용됩니다.
  3. 파일 업로드. 미디어 파일을 재개 가능한 세션 URI에 전송합니다.

또한 재개 가능한 업로드를 사용하는 앱에는 중단된 업로드를 다시 시작하는 코드가 있어야 합니다. 업로드가 중단되면 성공적으로 수신된 데이터 양을 확인한 후 중단된 지점부터 업로드를 다시 시작합니다.

참고: 업로드 URI는 일주일 후에 만료됩니다.

1단계: 재개 가능한 세션 시작

재개 가능한 업로드를 시작하려면 메서드의 /upload URI에 POST 요청을 전송하고 쿼리 매개변수 uploadType=resumable을 추가합니다. 예를 들면 다음과 같습니다.

POST https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable

시작 요청에는 본문이 비어 있거나 메타데이터만 포함되어 있습니다. 이후 요청에서는 업로드할 실제 파일 콘텐츠를 전송합니다.

시작 요청에는 다음 HTTP 헤더를 사용합니다.

  • X-Upload-Content-Type. 이후 요청에서 전송할 업로드 데이터의 미디어 MIME 유형으로 설정합니다.
  • X-Upload-Content-Length. 이후 요청에서 전송할 업로드 데이터의 바이트 수로 설정합니다.  이 요청 시점의 길이를 모르면 이 헤더를 생략할 수 있습니다.
  • Content-Type(메타데이터를 제공하는 경우). 메타데이터의 데이터 유형에 따라 설정합니다.
  • Content-Length. 이 시작 요청 본문에 제공된 바이트 수로 설정합니다. 단위 분할된 전송 인코딩을 사용하는 경우에는 설정할 필요가 없습니다.

파일 업로드와 관련된 각 메서드에서 허용되는 미디어 MIME 유형 및 크기 제한 목록은 API 참조를 확인하세요.

예: 재개 가능한 세션 시작 요청

다음 예시에서는 Google BigQuery API로 재개 가능한 세션을 시작하는 방법을 보여줍니다.

POST /upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Type: */*
X-Upload-Content-Length: 2000000

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}

참고: 메타데이터가 없는 재개 가능한 업데이트 시작 요청의 경우 요청 본문을 비워 두고 Content-Length 헤더를 0으로 설정하세요.

다음 섹션에서는 응답을 처리하는 방법을 설명합니다.

2단계: 재개 가능한 세션 URI 저장

세션 시작 요청이 성공하면 API 서버는 200 OK HTTP 상태 코드를 응답으로 반환합니다. 또한 재개 가능한 세션 URI가 지정된 Location 헤더를 제공합니다. 아래 예와 같이 Location 헤더에는 이 세션에서 사용할 고유한 업로드 ID를 제공하는 upload_id 쿼리 매개변수가 포함되어 있습니다.

예: 재개 가능한 세션 시작 응답

1단계의 요청에 대한 응답은 다음과 같습니다.

HTTP/1.1 200 OK
Location: https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2
Content-Length: 0

위 예시의 응답에 있는 Location 헤더 값이 실제 파일 업로드 또는 업로드 상태를 쿼리할 때 HTTP 엔드포인트로 사용할 세션 URI입니다.

이후 요청에서 사용할 수 있도록 세션 URI를 복사 및 저장합니다.

3단계: 파일 업로드

파일을 업로드하려면 PUT 요청을 이전 단계에서 가져온 업로드 URI에 전송합니다. 업로드 요청 형식은 다음과 같습니다.

PUT session_uri

재개 가능한 파일 업로드 요청을 전송할 때 사용되는 HTTP 헤더에는 Content-Length가 포함되며 이 요청에서 업로드하는 바이트 수로 설정됩니다. 보통은 업로드 파일 크기입니다.

예: 재개 가능한 파일 업로드 요청

다음은 현재 예시에서 전체 2,000,000바이트 크기의 CSV, JSON, AVRO, PARQUET, ORC 파일을 업로드할 수 있는 재개 가능한 요청입니다.

PUT https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
Content-Length: 2000000
Content-Type: */*

bytes 0-1999999

요청이 성공하면 서버에서는 HTTP 201 Created 및 이 리소스와 관련된 메타데이터를 응답으로 반환합니다. 재개 가능한 세션의 시작 요청이 PUT이었다면 기존 리소스를 업데이트하기 위해 성공 응답이 200 OK가 되며 이 리소스와 관련된 메타데이터도 반환됩니다.

업로드 요청이 중단되거나 서버로부터 HTTP 503 Service Unavailable 또는 기타 5xx 응답을 받은 경우 중단된 업로드 재개에서 설명된 절차를 따릅니다.  


파일의 단위별 업로드

재개 가능한 업로드를 사용하면 한 파일을 여러 단위로 나누어 각 단위를 순서대로 업로드하는 일련의 요청을 전송할 수 있습니다. 부가적인 요청으로 인한 성능 저하가 발생하고 일반적으로 필요하지 않으므로 선호되는 방식은 아닙니다. 하지만 단일 요청으로 전송되는 데이터 양을 줄이기 위해 파일을 단위로 나누어야 할 수도 있습니다. Google App Engine 요청의 특정 클래스처럼 개별 요청에 고정된 시간 제한이 적용되는 경우 유용합니다. 또한 기본적으로 업로드 진행률이 제공되지 않는 이전 브라우저에서 업로드 진행률을 표시하는 등의 작업도 가능합니다.


중단된 업로드 다시 시작

응답을 받기 전에 업로드 요청이 종료되거나 서버로부터 HTTP 503 Service Unavailable 응답을 받은 경우에는 중단된 업로드를 다시 시작해야 합니다. 이렇게 하려면 다음 안내를 따르세요.

  1. 상태 요청.PUT 요청을 업로드 URI에 전송하여 현재 업로드 상태를 쿼리합니다. 이 요청의 HTTP 헤더에는 파일에서의 현재 위치를 알 수 없음을 나타내는 Content-Range 헤더가 포함되어야 합니다.  예를 들어 총 파일 길이가 2,000,000이라면 Content-Range*/2000000으로 설정합니다. 파일 전체 크기를 모르면 Content-Range*/*로 설정합니다.

    참고: 업로드가 중단된 경우가 아니라도 각 단위 사이의 상태를 요청할 수 있습니다. 이러한 요청은 기존 브라우저에서 업로드 진행률을 표시하려는 경우에 유용합니다.

  2. 업로드된 바이트 수 가져오기. 상태 쿼리의 응답을 처리합니다. 서버에서 응답의 Range 헤더를 사용해 지금까지 수신한 바이트를 지정합니다.  예를 들어 Range 헤더 값이 0-299999이면 파일의 처음 300,000바이트가 수신되었음을 나타냅니다.
  3. 남은 데이터 업로드 - 마지막으로 요청을 재개할 위치를 결정했다면 나머지 데이터 또는 현재 청크를 전송합니다. 어떤 경우든 남은 데이터를 별도의 단위로 다루어야 하므로 업로드를 재개할 때 Content-Range 헤더를 전송해야 합니다.
예: 중단된 업로드 재개

1) 업로드 상태 요청

다음 요청에서는 Content-Range 헤더를 사용해 2,000,000바이트 크기의 파일에서 현재 위치를 알 수 없음을 나타냅니다.

PUT {session_uri} HTTP/1.1
Content-Length: 0
Content-Range: bytes */2000000

2) 응답에서 지금까지 업로드된 바이트 수 추출

서버의 응답에서는 Range 헤더를 사용해 지금까지 파일의 처음 43바이트를 수신했음을 나타냅니다. Range 헤더의 범위 중 큰 값을 사용해 업로드를 재개할 위치를 결정합니다.

HTTP/1.1 308 Resume Incomplete
Content-Length: 0
Range: 0-42

참고: 업로드가 완료되면 상태 응답은 201 Created 또는 200 OK일 수 있습니다. 모든 바이트가 업로드되었으나 클라이언트가 서버 응답을 수신하기 전에 연결이 끊기면 이러한 상황이 발생할 수 있습니다.

3) 중단된 지점부터 업로드 재개

다음 요청에서는 43바이트부터 파일의 나머지 바이트를 전송해 업로드를 재개합니다.

PUT {session_uri} HTTP/1.1
Content-Length: 1999957
Content-Range: bytes 43-1999999/2000000

bytes 43-1999999

권장사항

미디어를 업로드할 때는 오류 처리와 관련된 일부 권장사항을 알면 도움이 됩니다.

  • 연결 중단 또는 기타 5xx 오류로 인해 실패한 업로드를 재개하거나 재시도합니다.
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • 업로드 요청을 재개하거나 재시도할 때 5xx 서버 오류가 반환되면 지수 백오프 전략을 사용합니다. 서버가 과부하되면 이러한 오류가 발생할 수 있습니다. 요청량 또는 네트워크 트래픽이 많은 기간에 지수 백오프를 사용하면 이러한 문제가 완화될 수 있습니다.
  • 다른 종류의 요청을 지수 백오프로 처리하면 안 되지만 그 중 상당수를 여전히 재시도할 수 있습니다. 요청을 재시도할 때는 재시도 횟수를 제한합니다. 예를 들어 오류가 보고되기 전에 10회 이하로 재시도하도록 코드를 제한할 수 있습니다.
  • 재개 가능한 업로드를 수행할 때 처음부터 전체 업로드를 다시 시작하여 404 Not Found 오류를 처리합니다.

지수 백오프

지수 백오프는 클라이언트에서 시간 간격을 늘려 실패한 요청을 주기적으로 다시 시도하는 네트워크 애플리케이션용 표준 오류 처리 전략입니다. 많은 양의 요청 또는 네트워크 트래픽으로 인해 서버에서 오류를 반환하는 경우 지수 백오프는 이러한 오류를 처리하는 데 효과적인 전략일 수 있습니다. 반대로 잘못된 승인 사용자 인증 정보 또는 파일을 찾을 수 없는 오류 등 네트워크 트래픽 양이나 응답 시간과 무관한 오류를 처리할 때는 적절한 전략이 아닙니다.

지수 백오프를 적절하게 사용하면 대역폭 사용량의 효율성을 높이고, 성공적인 응답을 가져오는 데 필요한 요청 수를 줄이며, 동시 환경에서의 요청 처리량을 극대화할 수 있습니다.

간단한 지수 백오프 구현 흐름은 다음과 같습니다.

  1. API에 요청을 전송합니다.
  2. 요청을 재시도해야 함을 알리는 HTTP 503 응답을 수신합니다.
  3. 1초 + random_number_milliseconds를 대기한 후 요청을 재시도합니다.
  4. 요청을 재시도해야 함을 알리는 HTTP 503 응답을 수신합니다.
  5. 2초 + random_number_milliseconds를 대기한 후 요청을 재시도합니다.
  6. 요청을 재시도해야 함을 알리는 HTTP 503 응답을 수신합니다.
  7. 4초 + random_number_milliseconds를 대기한 후 요청을 재시도합니다.
  8. 요청을 재시도해야 함을 알리는 HTTP 503 응답을 수신합니다.
  9. 8초 + random_number_milliseconds를 대기한 후 요청을 재시도합니다.
  10. 요청을 재시도해야 함을 알리는 HTTP 503 응답을 수신합니다.
  11. 16초 + random_number_milliseconds를 대기한 후 요청을 재시도합니다.
  12. 중지합니다. 오류를 보고하거나 로깅합니다.

위 흐름에서 random_number_milliseconds는 1,000밀리초 이하의 임의 숫자입니다. 보다 균일하게 부하를 분산하고 서버 과부하 가능성을 방지하므로 이와 같은 임의의 작은 지연이 필요합니다. random_number_milliseconds 값은 대기 후 매번 재정의해야 합니다.

참고: 대기 시간은 항상 (2 ^ n) + random_number_milliseconds이며, 여기서 n은 단순 증가 정수로서 처음에는 0으로 정의됩니다. 정수 n은 반복(요청)할 때마다 1씩 증가합니다.

n이 5일 때 종료하도록 알고리즘이 설정되어 있습니다. 이러한 제한은 클라이언트의 무제한 재시도를 방지하고 요청이 '복구 불가능한 오류'로 간주되기 전에 약 32초의 총 지연 시간을 발생시킵니다. 특히 긴 업로드가 진행 중인 경우에는 최대 재시도 횟수를 늘리는 것이 좋습니다. 단, 재시도 지연 시간을 합리적인 시간(1분 미만)으로 제한해야 합니다.

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

도움이 필요하시나요? 지원 페이지를 방문하세요.