Stay organized with collections
Save and categorize content based on your preferences.
Load JSON data from Cloud Storage
You can load newline-delimited JSON (ndJSON) data from Cloud Storage into a new table
or partition, or append to or overwrite an existing table or partition. When
your data is loaded into BigQuery, it is converted into columnar format
for Capacitor
(BigQuery's storage format).
The ndJSON format is the same format as the
JSON Lines format.
Limitations
You are subject to the following limitations when you load data into
BigQuery from a Cloud Storage bucket:
BigQuery does not guarantee data consistency for external data
sources. Changes to the underlying data while a query is running can result in
unexpected behavior.
BigQuery doesn't support
Cloud Storage object versioning. If you
include a generation number in the Cloud Storage URI, then the load job
fails.
When you load JSON files into BigQuery, note the following:
JSON data must be newline-delimited, or ndJSON. Each JSON object must be on a
separate line in the file.
If you use gzip
compression,
BigQuery cannot read the data in parallel. Loading compressed
JSON data into BigQuery is slower than loading uncompressed
data.
You cannot include both compressed and uncompressed files in the same load
job.
The maximum size for a gzip file is 4 GB.
BigQuery supports the JSON type even if schema information is
not known at the time of ingestion. A field that is declared as JSON type
is loaded with the raw JSON values.
If you use the BigQuery API to load an integer outside the range
of [-253+1, 253-1] (usually this means
larger than 9,007,199,254,740,991), into an integer (INT64)
column, pass it as a string to avoid data corruption. This issue is
caused by a limitation on integer size in JSON or ECMAScript. For more
information, see
the Numbers section of RFC 7159.
When you load CSV or JSON data, values in DATE columns must use the dash
(-) separator and the date must be in the following format: YYYY-MM-DD
(year-month-day).
When you load JSON or CSV data, values in TIMESTAMP columns
must use a dash (-) or slash (/) separator for the date portion of the
timestamp, and the date must be in one of the following formats: YYYY-MM-DD (year-month-day) or
YYYY/MM/DD (year/month/day).
The hh:mm:ss (hour-minute-second) portion of the timestamp must use a colon
(:) separator.
Your files must meet the JSON file size limits described in the
load jobs limits.
Before you begin
Grant Identity and Access Management (IAM) roles that give users the necessary
permissions to perform each task in this document, and create a dataset
to store your data.
Required permissions
To load data into BigQuery, you need IAM permissions to run a load job and load data into BigQuery tables and partitions. If you are loading data from Cloud Storage, you also need IAM permissions to access the bucket that contains your data.
Permissions to load data into BigQuery
To load data into a new BigQuery table or partition or to append or overwrite an existing table or partition, you need the following IAM permissions:
bigquery.tables.create
bigquery.tables.updateData
bigquery.tables.update
bigquery.jobs.create
Each of the following predefined IAM roles includes the permissions that you need in order to load data into a BigQuery table or partition:
roles/bigquery.dataEditor
roles/bigquery.dataOwner
roles/bigquery.admin (includes the bigquery.jobs.create permission)
bigquery.user (includes the bigquery.jobs.create permission)
bigquery.jobUser (includes the bigquery.jobs.create permission)
Additionally, if you have the bigquery.datasets.create permission, you can create and
update tables using a load job in the datasets that you create.
To get the permissions that
you need to load data from a Cloud Storage bucket,
ask your administrator to grant you the
Storage Admin (roles/storage.admin) IAM role on the bucket.
For more information about granting roles, see Manage access to projects, folders, and organizations.
This predefined role contains
the permissions required to load data from a Cloud Storage bucket. To see the exact permissions that are
required, expand the Required permissions section:
Required permissions
The following permissions are required to load data from a Cloud Storage bucket:
storage.buckets.get
storage.objects.get
storage.objects.list (required if you are using a URI wildcard)
You can use the gzip utility to compress JSON files. Note that gzip performs
full file compression, unlike the file content compression performed by
compression codecs for other file formats, such as Avro. Using gzip to
compress your JSON files might have a performance impact; for more information
about the trade-offs, see
Loading compressed and uncompressed data.
Loading JSON data into a new table
To load JSON data from Cloud Storage into a new BigQuery
table:
import("context""fmt""cloud.google.com/go/bigquery")// importJSONExplicitSchema demonstrates loading newline-delimited JSON data from Cloud Storage// into a BigQuery table and providing an explicit schema for the data.funcimportJSONExplicitSchema(projectID,datasetID,tableIDstring)error{// projectID := "my-project-id"// datasetID := "mydataset"// tableID := "mytable"ctx:=context.Background()client,err:=bigquery.NewClient(ctx,projectID)iferr!=nil{returnfmt.Errorf("bigquery.NewClient: %v",err)}deferclient.Close()gcsRef:=bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/us-states/us-states.json")gcsRef.SourceFormat=bigquery.JSONgcsRef.Schema=bigquery.Schema{{Name:"name",Type:bigquery.StringFieldType},{Name:"post_abbr",Type:bigquery.StringFieldType},}loader:=client.Dataset(datasetID).Table(tableID).LoaderFrom(gcsRef)loader.WriteDisposition=bigquery.WriteEmptyjob,err:=loader.Run(ctx)iferr!=nil{returnerr}status,err:=job.Wait(ctx)iferr!=nil{returnerr}ifstatus.Err()!=nil{returnfmt.Errorf("job completed with error: %v",status.Err())}returnnil}
importcom.google.cloud.bigquery.BigQuery;importcom.google.cloud.bigquery.BigQueryException;importcom.google.cloud.bigquery.BigQueryOptions;importcom.google.cloud.bigquery.Field;importcom.google.cloud.bigquery.FormatOptions;importcom.google.cloud.bigquery.Job;importcom.google.cloud.bigquery.JobInfo;importcom.google.cloud.bigquery.LoadJobConfiguration;importcom.google.cloud.bigquery.Schema;importcom.google.cloud.bigquery.StandardSQLTypeName;importcom.google.cloud.bigquery.TableId;// Sample to load JSON data from Cloud Storage into a new BigQuery tablepublicclassLoadJsonFromGCS{publicstaticvoidrunLoadJsonFromGCS(){// TODO(developer): Replace these variables before running the sample.StringdatasetName="MY_DATASET_NAME";StringtableName="MY_TABLE_NAME";StringsourceUri="gs://cloud-samples-data/bigquery/us-states/us-states.json";Schemaschema=Schema.of(Field.of("name",StandardSQLTypeName.STRING),Field.of("post_abbr",StandardSQLTypeName.STRING));loadJsonFromGCS(datasetName,tableName,sourceUri,schema);}publicstaticvoidloadJsonFromGCS(StringdatasetName,StringtableName,StringsourceUri,Schemaschema){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.BigQuerybigquery=BigQueryOptions.getDefaultInstance().getService();TableIdtableId=TableId.of(datasetName,tableName);LoadJobConfigurationloadConfig=LoadJobConfiguration.newBuilder(tableId,sourceUri).setFormatOptions(FormatOptions.json()).setSchema(schema).build();// Load data from a GCS JSON file into the tableJobjob=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 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|InterruptedExceptione){System.out.println("Column not added during load append \n"+e.toString());}}}
// Import the Google Cloud client librariesconst{BigQuery}=require('@google-cloud/bigquery');const{Storage}=require('@google-cloud/storage');// Instantiate clientsconstbigquery=newBigQuery();conststorage=newStorage();/** * 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. */constbucketName='cloud-samples-data';constfilename='bigquery/us-states/us-states.json';asyncfunctionloadJSONFromGCS(){// Imports a GCS file into a table with manually defined schema./** * TODO(developer): Uncomment the following lines before running the sample. */// const datasetId = "my_dataset";// const tableId = "my_table";// Configure the load job. For full list of options, see:// https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationLoadconstmetadata={sourceFormat:'NEWLINE_DELIMITED_JSON',schema:{fields:[{name:'name',type:'STRING'},{name:'post_abbr',type:'STRING'},],},location:'US',};// Load data from a Google Cloud Storage file into the tableconst[job]=awaitbigquery.dataset(datasetId).table(tableId).load(storage.bucket(bucketName).file(filename),metadata);// load() waits for the job to finishconsole.log(`Job ${job.id} completed.`);// Check the job's status for errorsconsterrors=job.status.errors;if(errors && errors.length > 0){throwerrors;}}
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';// instantiate the bigquery table service$bigQuery = new BigQueryClient([ 'projectId' => $projectId,]);$dataset = $bigQuery->dataset($datasetId);$table = $dataset->table('us_states');// create the import job$gcsUri = 'gs://cloud-samples-data/bigquery/us-states/us-states.json';$schema = [ 'fields' => [ ['name' => 'name', 'type' => 'string'], ['name' => 'post_abbr', 'type' => 'string'] ]];$loadConfig = $table->loadFromStorage($gcsUri)->schema($schema)->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 errorsif (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);}
Use the
Client.load_table_from_uri()
method to start a load job from Cloud Storage. To use JSONL,
set the LoadJobConfig.source_format
property
to the string NEWLINE_DELIMITED_JSON and pass the job config as the
job_config argument to the load_table_from_uri() method.
fromgoogle.cloudimportbigquery# 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"job_config=bigquery.LoadJobConfig(schema=[bigquery.SchemaField("name","STRING"),bigquery.SchemaField("post_abbr","STRING"),],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,location="US",# Must match the destination dataset location.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))
Use the
Dataset.load_job()
method to start a load job from Cloud Storage. To use JSONL,
set the format parameter to "json".
require"google/cloud/bigquery"defload_table_gcs_jsondataset_id="your_dataset_id"bigquery=Google::Cloud::Bigquery.newdataset=bigquery.datasetdataset_idgcs_uri="gs://cloud-samples-data/bigquery/us-states/us-states.json"table_id="us_states"load_job=dataset.load_jobtable_id,gcs_uri,format:"json"do|schema|schema.string"name"schema.string"post_abbr"endputs"Starting job #{load_job.job_id}"load_job.wait_until_done!# Waits for table load to complete.puts"Job finished."table=dataset.tabletable_idputs"Loaded #{table.rows_count} rows to table #{table.id}"end
Loading nested and repeated JSON data
BigQuery supports loading nested and
repeated data from source formats that support object-based schemas, such as
JSON, Avro, ORC, Parquet, Firestore, and Datastore.
One JSON object,
including any nested or repeated fields, must appear on each line.
The following example shows sample nested or repeated data. This table contains
information about people. It consists of the following fields:
id
first_name
last_name
dob (date of birth)
addresses (a nested and repeated field)
addresses.status (current or previous)
addresses.address
addresses.city
addresses.state
addresses.zip
addresses.numberOfYears (years at the address)
The JSON data file would look like the following. Notice that the address field
contains an array of values (indicated by [ ]).
{"id":"1","first_name":"John","last_name":"Doe","dob":"1968-01-22","addresses":[{"status":"current","address":"123 First Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456 Main Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]}
{"id":"2","first_name":"Jane","last_name":"Doe","dob":"1980-10-16","addresses":[{"status":"current","address":"789 Any Avenue","city":"New York","state":"NY","zip":"33333","numberOfYears":"2"},{"status":"previous","address":"321 Main Street","city":"Hoboken","state":"NJ","zip":"44444","numberOfYears":"3"}]}
The schema for this table would look like the following:
BigQuery supports loading semi-structured data, in which a field
can take values of different types. The following example shows data similar to
the preceding
nested and repeated JSON data
example, except that the address field can be a STRING, a STRUCT, or
an ARRAY:
{"id":"1","first_name":"John","last_name":"Doe","dob":"1968-01-22","address":"123 First Avenue, Seattle WA 11111"}
{"id":"2","first_name":"Jane","last_name":"Doe","dob":"1980-10-16","address":{"status":"current","address":"789 Any Avenue","city":"New York","state":"NY","zip":"33333","numberOfYears":"2"}}
{"id":"3","first_name":"Bob","last_name":"Doe","dob":"1982-01-10","address":[{"status":"current","address":"789 Any Avenue","city":"New York","state":"NY","zip":"33333","numberOfYears":"2"}, "321 Main Street Hoboken NJ 44444"]}
You can load this data into BigQuery by using the following
schema:
The address field is loaded into a column with type
JSON that allows
it to hold
the mixed types in the example. You can ingest data as JSON whether it
contains mixed types or not. For example, you could specify JSON instead of
STRING as the type for the first_name field. For more information, see
Working with JSON data in GoogleSQL.
Appending to or overwriting a table with JSON data
You can load additional data into a table either from source files or by
appending query results.
In the Google Cloud console, use the Write preference option to specify
what action to take when you load data from a source file or from a query
result.
You have the following options when you load additional data into a table:
Console option
bq tool flag
BigQuery API property
Description
Write if empty
Not supported
WRITE_EMPTY
Writes the data only if the table is empty.
Append to table
--noreplace or --replace=false; if
--[no]replace is unspecified, the default is append
WRITE_APPEND
(Default)
Appends the data to the end of the table.
Overwrite table
--replace or --replace=true
WRITE_TRUNCATE
Erases all existing data in a table before writing the new data.
This action also deletes the table schema, row level security, and removes any
Cloud KMS key.
If you load data into an existing table, the load job can append the data or
overwrite the table.
You can append or overwrite a table by using one of the following:
The Google Cloud console
The bq command-line tool's bq load command
The jobs.insert API method and configuring a load job
BigQuery supports loading hive-partitioned JSON data stored on
Cloud Storage and populates the hive-partitioning columns as columns in
the destination BigQuery managed table. For more information, see
Load externally partitioned data.
Details of loading JSON data
This section describes how BigQuery parses various data types when
loading JSON data.
Data types
Boolean. BigQuery can parse any of the following pairs for
Boolean data: 1 or 0, true or false, t or f, yes or no, or y or n (all case
insensitive). Schema autodetection
automatically detects any of these except 0 and 1.
Bytes. Columns with BYTES types must be encoded as Base64.
Date. Columns with DATE types must be in the format YYYY-MM-DD.
Datetime. Columns with DATETIME types must be in the format YYYY-MM-DD
HH:MM:SS[.SSSSSS].
Geography. Columns with GEOGRAPHY types must contain strings in one of the
following formats:
Interval. Columns with INTERVAL types must be in
ISO 8601 format
PYMDTHMS, where:
P = Designator that indicates that the value represents a duration. You must
always include this.
Y = Year
M = Month
D = Day
T = Designator that denotes the time portion of the duration. You must
always include this.
H = Hour
M = Minute
S = Second. Seconds can be denoted as a whole value or as a fractional value
of up to six digits, at microsecond precision.
You can indicate a negative value by prepending a dash (-).
The following list shows examples of valid data:
P-10000Y0M-3660000DT-87840000H0M0S
P0Y0M0DT0H0M0.000001S
P10000Y0M3660000DT87840000H0M0S
To load INTERVAL data, you must use the bq load command and use the --schema
flag to specify a schema. You can't upload INTERVAL data by using the console.
Time. Columns with TIME types must be in the format HH:MM:SS[.SSSSSS].
Timestamp. BigQuery accepts various timestamp formats.
The timestamp must include a date portion and a time portion.
The date portion can be formatted as YYYY-MM-DD or YYYY/MM/DD.
The timestamp portion must be formatted as HH:MM[:SS[.SSSSSS]] (seconds and
fractions of seconds are optional).
The date and time must be separated by a space or 'T'.
Optionally, the date and time can be followed by a UTC offset or the UTC zone
designator (Z). For more information, see
Time zones.
For example, any of the following are valid timestamp values:
2018-08-19T12:11
2018-08-19T12:11:35
2018-08-19T12:11:35.22
2018/08/19T12:11
2018-07-05T12:54:00 UTC
2018-08-19T07:11:35.220 -05:00
2018-08-19T12:11:35.220Z
If you provide a schema, BigQuery also accepts Unix epoch time for
timestamp values. However, schema autodetection doesn't detect this case, and
treats the value as a numeric or string type instead.
Examples of Unix epoch timestamp values:
1534680695
1.534680695e12
Array (repeated field). The value must be a JSON array or null. JSON
null is converted to SQL NULL. The array itself cannot contain null
values.
Schema auto-detection
This section describes the behavior of
schema auto-detection when loading JSON files.
JSON nested and repeated fields
BigQuery infers nested and repeated fields in JSON files. If a
field value is a JSON object, then BigQuery loads the column as a
RECORD type. If a field value is an array, then BigQuery loads
the column as a repeated column. For an example of JSON data with nested and
repeated data, see
Loading nested and repeated JSON data.
String conversion
If you enable schema auto-detection, then BigQuery converts
strings into Boolean, numeric, or date/time types when possible. For example,
using the following JSON data, schema auto-detection converts the id field
to an INTEGER column:
BigQuery expects JSON data to be UTF-8 encoded. If you have
JSON files with other supported encoding types, you should explicitly specify
the encoding by using the --encoding flag so that
BigQuery converts the data to UTF-8.
BigQuery supports the following encoding types for JSON files:
UTF-8
ISO-8859-1
UTF-16BE (UTF-16 Big Endian)
UTF-16LE (UTF-16 Little Endian)
UTF-32BE (UTF-32 Big Endian)
UTF-32LE (UTF-32 Little Endian)
JSON options
To change how BigQuery parses JSON data, specify additional
options in the Google Cloud console, the bq command-line tool, the API, or the client
libraries.
(Optional) The maximum number of bad records that BigQuery can
ignore when running the job. If the number of bad records exceeds this
value, an invalid error is returned in the job result. The default value
is `0`, which requires that all records are valid.
(Optional) Indicates whether BigQuery should allow extra values
that are not represented in the table schema. If true, the extra values
are ignored. If false, records with extra columns are treated as bad
records, and if there are too many bad records, an invalid error is
returned in the job result. The default value is false. The `sourceFormat`
property determines what BigQuery treats as an extra value:
CSV: trailing columns, JSON: named values that don't match any column
names.
(Optional) The character encoding of the data. The supported values are
UTF-8, ISO-8859-1, UTF-16BE, UTF-16LE, UTF-32BE, or UTF-32LE.
The default value is UTF-8.
(Optional)
Default time zone that is applied when parsing timestamp values
that have no specific time zone. Check
valid time zone names.
If this value is not present, the timestamp values without specific time
zone is parsed using default time zone UTC.
(Optional)
Format elements
that define how the DATE values are formatted in the input files (for
example, MM/DD/YYYY). If this value is present, this format is
the only compatible DATE format.
Schema autodetection
will also decide DATE column type based on this format instead of the
existing format. If this value is not present, the DATE field is parsed with
the
default formats.
(Optional)
Format elements
that define how the DATETIME values are formatted in the input files (for
example, MM/DD/YYYY HH24:MI:SS.FF3). If this value is present,
this format is the only compatible DATETIME format.
Schema autodetection
will also decide DATETIME column type based on this format instead of the
existing format. If this value is not present, the DATETIME field is parsed
with the
default formats.
(Optional)
Format elements
that define how the TIME values are formatted in the input files (for
example, HH24:MI:SS.FF3). If this value is present, this format
is the only compatible TIME format.
Schema autodetection
will also decide TIME column type based on this format instead of the
existing format. If this value is not present, the TIME field is parsed with
the
default formats.
(Optional)
Format elements
that define how the TIMESTAMP values are formatted in the input files (for
example, MM/DD/YYYY HH24:MI:SS.FF3). If this value is present,
this format is the only compatible TIMESTAMP format.
Schema autodetection
will also decide TIMESTAMP column type based on this format instead of the
existing format. If this value is not present, the TIMESTAMP field is parsed
with the
default formats.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2026-09-30 UTC."],[],[]]