This page provides an overview of loading Parquet data from Cloud Storage into BigQuery.
Parquet is an open source column-oriented data format that is widely used in the Apache Hadoop ecosystem.
When you load Parquet data from Cloud Storage, you can load the data into a new table or partition, or you can 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).
When you load data from Cloud Storage into a BigQuery table, the dataset that contains the table must be in the same regional or multi- regional location as the Cloud Storage bucket.
For information about loading Parquet data from a local file, see Loading data from local files.
Parquet schemas
When you load Parquet files into BigQuery, the table schema is automatically retrieved from the self-describing source data. When BigQuery retrieves the schema from the source data, the alphabetically last file is used.
For example, you have the following Parquet files in Cloud Storage:
gs://mybucket/00/ a.parquet z.parquet gs://mybucket/01/ b.parquet
Running this command in the bq
command-line tool loads all of the files (as a
comma-separated list), and the schema is derived from mybucket/01/b.parquet
:
bq load \ --source_format=PARQUET \ dataset.table \ "gs://mybucket/00/*.parquet","gs://mybucket/01/*.parquet"
When you load multiple Parquet files that have different schemas, identical columns specified in multiple schemas must have the same mode in each schema definition.
When BigQuery detects the schema, some Parquet data types are converted to BigQuery data types to make them compatible with BigQuery SQL syntax. For more information, see Parquet conversions.
Parquet compression
BigQuery supports the following compression codecs for data blocks in Parquet files:
GZip
LZO_1C
andLZO_1X
Snappy
ZSTD
Required permissions
When you load data into BigQuery, you need permissions to run a load job and permissions that let you load data into new or existing BigQuery tables and partitions. If you are loading data from Cloud Storage, you also need permissions to access to the bucket that contains your data.
BigQuery permissions
At a minimum, the following permissions are required to load data into BigQuery. These permissions are required if you are loading data into a new table or partition, or if you are appending or overwriting a table or partition.
bigquery.tables.create
bigquery.tables.updateData
bigquery.jobs.create
The following predefined IAM roles include both
bigquery.tables.create
and bigquery.tables.updateData
permissions:
bigquery.dataEditor
bigquery.dataOwner
bigquery.admin
The following predefined IAM roles include bigquery.jobs.create
permissions:
bigquery.user
bigquery.jobUser
bigquery.admin
In addition, if a user has bigquery.datasets.create
permissions, when that
user creates a dataset, they are granted bigquery.dataOwner
access to it.
bigquery.dataOwner
access lets the user create and
update tables in the dataset by using a load job.
For more information on IAM roles and permissions in BigQuery, see Access control.
Cloud Storage permissions
To load data from a Cloud Storage bucket, you must be granted
storage.objects.get
permissions. If you are using a URI wildcard,
you must also have storage.objects.list
permissions.
The predefined IAM role storage.objectViewer
can be granted to provide both storage.objects.get
and storage.objects.list
permissions.
Loading Parquet data into a new table
You can load Parquet data into a new table by using one of the following:
- The Cloud Console
- The
bq
command-line tool'sbq load
command - The
jobs.insert
API method and configuring aload
job - The client libraries
To load Parquet data from Cloud Storage into a new BigQuery table:
Console
In the Cloud Console, open the BigQuery page.
In the Explorer panel, expand your project and select a dataset.
In the details panel, click Create table.
On the Create table page, in the Source section:
For Create table from, select Cloud Storage.
In the source field, browse to or enter the Cloud Storage URI. Note that you cannot include multiple URIs in the Cloud Console, but wildcards are supported. The Cloud Storage bucket must be in the same location as the dataset that contains the table you're creating.
For File format, select Parquet.
On the Create table page, in the Destination section:
For Dataset name, choose the appropriate dataset.
Verify that Table type is set to Native table.
In the Table name field, enter the name of the table you're creating in BigQuery.
In the Schema section, no action is necessary. The schema is self-described in Parquet files.
(Optional) To partition the table, choose your options in the Partition and cluster settings:
- To create a partitioned table,
click No partitioning, select Partition by field and choose a
DATE
orTIMESTAMP
column. This option is unavailable if your schema does not include aDATE
orTIMESTAMP
column. - To create an ingestion-time partitioned table, click No partitioning and select Partition by ingestion time.
- To create a partitioned table,
click No partitioning, select Partition by field and choose a
(Optional) For Partitioning filter, click the Require partition filter box to require users to include a
WHERE
clause that specifies the partitions to query. Requiring a partition filter can reduce cost and improve performance. For more information, see Querying partitioned tables. This option is unavailable if No partitioning is selected.(Optional) To cluster the table, in the Clustering order box, enter between one and four field names.
(Optional) Click Advanced options.
- For Write preference, leave Write if empty selected. This option creates a new table and loads your data into it.
- For Number of errors allowed, accept the default value of
0
or enter the maximum number of rows containing errors that can be ignored. If the number of rows with errors exceeds this value, the job will result in aninvalid
message and fail. - For Unknown values, leave Ignore unknown values unchecked. This option applies only to CSV and JSON files.
- For Encryption, click Customer-managed key to use a Cloud Key Management Service key. If you leave the Google-managed key setting, BigQuery encrypts the data at rest.
Click Create table.
bq
Use the bq load
command, specify PARQUET
using the --source_format
flag, and include a Cloud Storage URI.
You can include a single URI, a comma-separated list of URIs, or a URI
containing a wildcard.
(Optional) Supply the --location
flag and set the value to your
location.
Other optional flags include:
--time_partitioning_type
: Enables time-based partitioning on a table and sets the partition type. Possible values areHOUR
,DAY
,MONTH
, andYEAR
. This flag is optional when you create a table partitioned on aDATE
,DATETIME
, orTIMESTAMP
column. The default partition type for time-based partitioning isDAY
.--time_partitioning_expiration
: An integer that specifies (in seconds) when a time-based partition should be deleted. The expiration time evaluates to the partition's UTC date plus the integer value.--time_partitioning_field
: TheDATE
orTIMESTAMP
column used to create a partitioned table. If time-based partitioning is enabled without this value, an ingestion-time partitioned table is created.--require_partition_filter
: When enabled, this option requires users to include aWHERE
clause that specifies the partitions to query. Requiring a partition filter can reduce cost and improve performance. For more information, see Querying partitioned tables.--clustering_fields
: A comma-separated list of up to four column names used to create a clustered table.--destination_kms_key
: The Cloud KMS key for encryption of the table data.For more information on partitioned tables, see:
For more information on clustered tables, see:
For more information on table encryption, see:
To load Parquet data into BigQuery, enter the following command:
bq --location=LOCATION load \ --source_format=FORMAT \ DATASET.TABLE \ PATH_TO_SOURCE
Replace the following:
LOCATION
: your location. The--location
flag is optional. For example, if you are using BigQuery in the Tokyo region, you can set the flag's value toasia-northeast1
. You can set a default value for the location using the .bigqueryrc file.FORMAT
:PARQUET
.DATASET
: an existing dataset.TABLE
: the name of the table into which you're loading data.PATH_TO_SOURCE
: a fully qualified Cloud Storage URI or a comma-separated list of URIs. Wildcards are also supported.
Examples:
The following command loads data from gs://mybucket/mydata.parquet
into a
table named mytable
in mydataset
.
bq load \
--source_format=PARQUET \
mydataset.mytable \
gs://mybucket/mydata.parquet
The following command loads data from gs://mybucket/mydata.parquet
into an
ingestion-time partitioned table named mytable
in mydataset
.
bq load \
--source_format=PARQUET \
--time_partitioning_type=DAY \
mydataset.mytable \
gs://mybucket/mydata.parquet
The following command loads data from gs://mybucket/mydata.parquet
into a
partitioned table named mytable
in mydataset
. The table is partitioned
on the mytimestamp
column.
bq load \
--source_format=PARQUET \
--time_partitioning_field mytimestamp \
mydataset.mytable \
gs://mybucket/mydata.parquet
The following command loads data from multiple files in gs://mybucket/
into a table named mytable
in mydataset
. The Cloud Storage URI uses a
wildcard.
bq load \
--source_format=PARQUET \
mydataset.mytable \
gs://mybucket/mydata*.parquet
The following command loads data from multiple files in gs://mybucket/
into a table named mytable
in mydataset
. The command includes a comma-
separated list of Cloud Storage URIs with wildcards.
bq load \
--source_format=PARQUET \
mydataset.mytable \
"gs://mybucket/00/*.parquet","gs://mybucket/01/*.parquet"
API
Create a
load
job that points to the source data in Cloud Storage.(Optional) Specify your location in the
location
property in thejobReference
section of the job resource.The
source URIs
property must be fully qualified, in the formatgs://BUCKET/OBJECT
. Each URI can contain one '*' wildcard character.Specify the Parquet data format by setting the
sourceFormat
property toPARQUET
.To check the job status, call
jobs.get(JOB_ID*)
, replacing JOB_ID with the ID of the job returned by the initial request.- If
status.state = DONE
, the job completed successfully. - If the
status.errorResult
property is present, the request failed, and that object includes information describing what went wrong. When a request fails, no table is created and no data is loaded. - If
status.errorResult
is absent, the job finished successfully; although, there might have been some non-fatal errors, such as problems importing a few rows. Non-fatal errors are listed in the returned job object'sstatus.errors
property.
- If
API notes:
Load jobs are atomic and consistent: if a load job fails, none of the data is available, and if a load job succeeds, all of the data is available.
As a best practice, generate a unique ID and pass it as
jobReference.jobId
when callingjobs.insert
to create a load job. This approach is more robust to network failure because the client can poll or retry on the known job ID.Calling
jobs.insert
on a given job ID is idempotent. You can retry as many times as you like on the same job ID, and at most one of those operations will succeed.
Go
Before trying this sample, follow the Go setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery Go API reference documentation.
Java
Before trying this sample, follow the Java setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery Java API reference documentation.
Node.js
Before trying this sample, follow the Node.js setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery Node.js API reference documentation.
PHP
Before trying this sample, follow the PHP setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery PHP API reference documentation.
Python
Before trying this sample, follow the Python setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery Python API reference documentation.
PARQUET
and pass the job config as the job_config
argument to
the load_table_from_uri()
method.
Appending to or overwriting a table with Parquet data
You can load additional data into a table either from source files or by appending query results.
In the 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 | None | 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 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 Cloud Console
- The
bq
command-line tool'sbq load
command - The
jobs.insert
API method and configuring aload
job - The client libraries
To append or overwrite a table with Parquet data:
Console
In the Cloud Console, open the BigQuery page.
In the Explorer panel, expand your project and select a dataset.
In the details panel, click Create table.
On the Create table page, in the Source section:
For Create table from, select Cloud Storage.
In the source field, browse to or enter the Cloud Storage URI. Note that you cannot include multiple URIs in the Cloud Console, but wildcards are supported. The Cloud Storage bucket must be in the same location as the dataset that contains the table you're appending or overwriting.
For File format, select Parquet.
On the Create table page, in the Destination section:
For Dataset name, choose the appropriate dataset.
In the Table name field, enter the name of the table you're appending or overwriting in BigQuery.
Verify that Table type is set to Native table.
In the Schema section, no action is necessary. The schema is self-described in Parquet files.
For Partition and cluster settings, leave the default values. You cannot convert a table to a partitioned or clustered table by appending or overwriting it, and the Cloud Console does not support appending to or overwriting partitioned or clustered tables in a load job.
Click Advanced options.
- For Write preference, choose Append to table or Overwrite table.
- For Number of errors allowed, accept the default value of
0
or enter the maximum number of rows containing errors that can be ignored. If the number of rows with errors exceeds this value, the job will result in aninvalid
message and fail. - For Unknown values, leave Ignore unknown values unchecked. This option applies only to CSV and JSON files.
For Encryption, click Customer-managed key to use a Cloud Key Management Service key. If you leave the Google-managed key setting, BigQuery encrypts the data at rest.
Click Create table.
bq
Enter the bq load
command with the --replace
flag to overwrite the
table. Use the --noreplace
flag to append data to the table. If no flag is
specified, the default is to append data. Supply the --source_format
flag
and set it to PARQUET
. Because Parquet schemas are automatically retrieved
from the self-describing source data, you do not need to provide a schema
definition.
(Optional) Supply the --location
flag and set the value to your
location.
Other optional flags include:
--destination_kms_key
: The Cloud KMS key for encryption of the table data.
bq --location=LOCATION load \ --[no]replace \ --source_format=FORMAT \ DATASET.TABLE \ PATH_TO_SOURCE
Replace the following:
location
: your location. The--location
flag is optional. You can set a default value for the location by using the .bigqueryrc file.format
:PARQUET
.dataset
: an existing dataset.table
: the name of the table into which you're loading data.path_to_source
: a fully qualified Cloud Storage URI or a comma-separated list of URIs. Wildcards are also supported.
Examples:
The following command loads data from gs://mybucket/mydata.parquet
and
overwrites a table named mytable
in mydataset
.
bq load \
--replace \
--source_format=PARQUET \
mydataset.mytable \
gs://mybucket/mydata.parquet
The following command loads data from gs://mybucket/mydata.parquet
and
appends data to a table named mytable
in mydataset
.
bq load \
--noreplace \
--source_format=PARQUET \
mydataset.mytable \
gs://mybucket/mydata.parquet
For information on appending and overwriting partitioned tables using the
bq
command-line tool, see
Appending to and overwriting partitioned table data.
API
Create a
load
job that points to the source data in Cloud Storage.(Optional) Specify your location in the
location
property in thejobReference
section of the job resource.The
source URIs
property must be fully qualified, in the formatgs://BUCKET/OBJECT
. You can include multiple URIs as a comma-separated list. Note that wildcards are also supported.Specify the data format by setting the
configuration.load.sourceFormat
property toPARQUET
.Specify the write preference by setting the
configuration.load.writeDisposition
property toWRITE_TRUNCATE
orWRITE_APPEND
.
Go
Before trying this sample, follow the Go setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery Go API reference documentation.
Java
Before trying this sample, follow the Java setup instructions in the BigQuery Quickstart Using Client Libraries. For more information, see the BigQuery Java API reference documentation.
Node.js
Before trying this sample, follow the Node.js setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery Node.js API reference documentation.
PHP
Before trying this sample, follow the PHP setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery PHP API reference documentation.
Python
Before trying this sample, follow the Python setup instructions in the
BigQuery Quickstart Using Client Libraries.
For more information, see the
BigQuery Python API reference documentation.
WRITE_TRUNCATE
.
Loading hive-partitioned Parquet data
BigQuery supports loading hive partitioned Parquet data stored on Cloud Storage and populates the hive partitioning columns as columns in the destination BigQuery managed table. For more information, see Loading externally partitioned data.
Parquet conversions
BigQuery converts Parquet data types to the following BigQuery data types:
Type conversions
BigQuery data type | ||
---|---|---|
BOOLEAN |
None | BOOLEAN |
INT32 | None, INTEGER (UINT_8 , UINT_16 ,
UINT_32 , INT_8 , INT_16 ,
INT_32 )
|
INTEGER |
INT32 | DECIMAL | NUMERIC, BIGNUMERIC, or STRING |
INT32 |
DATE |
DATE |
INT64 |
None, INTEGER (UINT_64 , INT_64 )
|
INTEGER |
INT64 | DECIMAL | NUMERIC, BIGNUMERIC, or STRING |
INT64 |
TIMESTAMP , precision=MILLIS
(TIMESTAMP_MILLIS )
|
TIMESTAMP |
INT64 |
TIMESTAMP , precision=MICROS
(TIMESTAMP_MICROS )
|
TIMESTAMP |
INT96 |
None | TIMESTAMP |
FLOAT |
None | FLOAT |
DOUBLE |
None | FLOAT |
BYTE_ARRAY |
None | BYTES |
BYTE_ARRAY |
STRING (UTF8 ) |
STRING |
FIXED_LEN_BYTE_ARRAY | DECIMAL | NUMERIC, BIGNUMERIC, or STRING |
FIXED_LEN_BYTE_ARRAY |
None | BYTES |
Nested groups are converted into
STRUCT
types.
Other combinations of Parquet types and converted types are not supported.
Decimal logical type
Decimal
logical types can be converted to NUMERIC
, BIGNUMERIC
, or STRING
types. The converted type depends
on the precision and scale parameters of the decimal
logical type and the
specified decimal target types. Specify the decimal target type as follows:
- For a load job using the
jobs.insert
API: use theJobConfigurationLoad.decimalTargetTypes
field. - For a load job using the
bq load
command in thebq
command-line tool: use the--decimal_target_types
flag. - For a query against a table with external sources:
use the
ExternalDataConfiguration.decimalTargetTypes
field. - For a persistent external table created with DDL:
use the
decimal_target_types
option.
Enum logical type
Enum
logical types can be converted to STRING
or BYTES
. Specify the converted target type as follows:
- For a load job using the
jobs.insert
API: use theJobConfigurationLoad.parquetOptions
field. - For a load job using the
bq load
command in thebq
command-line tool: use the--parquet_enum_as_string
flag. - For a persistent external table created with
bq mk
: use the--parquet_enum_as_string
flag.
List logical type
You can enable schema inference for Parquet LIST
logical types. BigQuery
checks whether the LIST
node is in the
standard form:
<optional | required> group <name> (LIST) {
repeated group list {
<optional | required> <element-type> element;
}
}
If yes, the corresponding field for the LIST
node in the converted schema is treated
as if the node has the following schema:
repeated <element-type> <name>
The nodes "list" and "element" are omitted.
- For a load job using the
jobs.insert
API: use theJobConfigurationLoad.parquetOptions
field. - For a load job using the
bq load
command in thebq
command-line tool: use the--parquet_enable_list_inference
flag. - For a persistent external table created with
bq mk
: use the flag--parquet_enable_list_inference
.
Column name conversions
A column name must contain only letters (a-z, A-Z), numbers (0-9), or underscores (_), and it must start with a letter or underscore. The maximum column name length is 300 characters. A column name cannot use any of the following prefixes:
_TABLE_
_FILE_
_PARTITION
Duplicate column names are not allowed even if the case differs. For example,
a column named Column1
is considered identical to a column named column1
.
You cannot load Parquet files containing columns that have a period (.) in the column name.
If a Parquet column name contains other characters (aside from a period), the
characters are replaced with underscores. You can add trailing underscores to
column names to avoid collisions. For example, if a Parquet file contains 2
columns Column1
and column1
, the columns are loaded as Column1
and
column1_
respectively.