Export data to Spanner (reverse ETL)

This document describes how you can set up a reverse extract, transform, andload (reverse ETL) workflow from BigQuery to Spanner. You cando this by using theEXPORT DATA statementto export data from BigQuery data sources, includingIceberg tables, to aSpanner table.

This reverse ETL workflow combines analytic capabilities inBigQuery with low latency and high throughput inSpanner. This workflow lets you serve data to application userswithout exhausting quotas and limits on BigQuery.

Before you begin

Required roles

To get the permissions that you need to export BigQuery data to Spanner, ask your administrator to grant you the following IAM roles on your project:

For more information about granting roles, seeManage access to projects, folders, and organizations.

You might also be able to get the required permissions throughcustom roles or otherpredefined roles.

Limitations

  • This feature is not supported in Assured Workloads.

  • The following BigQuery data types don't have equivalents inSpanner and are not supported:

Spanner database dialectUnsupported BigQuery types
All dialects
  • STRUCT
  • GEOGRAPHY
  • DATETIME
  • RANGE
  • TIME
GoogleSQL
  • BIGNUMERIC: The supportedNUMERIC type is not wide enough. Consider adding explicit casts to theNUMERIC type in the query.
  • The maximum size of an exported row cannot exceed 1 MiB.

  • Spanner enforces referential integrity during the export.If the target table is a child of another table (INTERLEAVE IN PARENT), or ifthe target table has foreign key constraints, the foreign keys and parent keywill be validated during the export. If an exported row is is written to atable with INTERLEAVE IN PARENT and the parent row doesn't exist, the exportwill fail with "Parent row is missing. Row cannot be written" error. If theexported row is written to a table with foreign key constraints and isreferencing a key that doesn't exist, the export will fail with"Foreign key constraint is violated" error. When exporting to multiple tables,we recommend sequencing the export to ensure that referential integrity willbe maintained through the export. This usually means exporting parent tablesand tables that are referenced by foreign keys before tables that referencethem.

    If the table that is the target of the export has foreign key constraints,or is a child of another table (INTERLEAVE IN PARENT), the parent table mustbe populated before a child table export, and should contain all thecorresponding keys. An attempt to export a child table while a parent tabledoes not have the complete set of relevant keys will fail.

  • A BigQuery job, such as an extract job toSpanner, has a maximum duration of 6 hours. For informationabout optimizing large extract jobs, seeExport optimization. Alternatively, consider splittingthe input into individual blocks of data, which may be exported as individualextract jobs.

  • Exports to Spanner are only supported for theBigQuery Enterprise or Enterprise Pluseditions. The BigQuery Standard edition and on-demandcompute are not supported.

  • You cannot use continuous queries to export to Spanner tableswithauto-generated primary keys.

  • You cannot use continuous queries to export to Spanner tablesin a PostgreSQL-dialect database.

  • When using continuous queries to export to a Spanner table,ensure that you choose a primary key that doesn't correspond to a monotonicallyincreasing integer in your BigQuery table. Doing so might cause performanceissues in your export. For information about primary keys in Spanner,and ways to mitigate these performance issues, seeChoose a primary key.

Configure exports withspanner_options option

You can use thespanner_options option to specify a destinationSpanner database and table. The configuration is expressed inthe form of a JSON string, as the following example shows:

EXPORTDATAOPTIONS(uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",format='CLOUD_SPANNER',spanner_options="""{      "table": "TABLE_NAME",      "change_timestamp_column": "CHANGE_TIMESTAMP",      "priority": "PRIORITY",      "tag": "TAG",   }""")

Replace the following:

  • PROJECT_ID: the name of your Google Cloud project.
  • INSTANCE_ID: the name of your database instance.
  • DATABASE_ID: the name of your database.
  • TABLE_NAME: the name of an existing destination table.
  • CHANGE_TIMESTAMP: the name of theTIMESTAMP type columnin the destination Spanner table. This option is usedduring export to track the timestamp of the most recent row update. Whenthis option is specified, the export first performs a read of the row in theSpanner table, to ensure that only the latest row update iswritten. We recommend specifying aTIMESTAMP type column when you run acontinuous export, where the ordering of changes torows with the same primary key is important.
  • PRIORITY (optional):priorityof the write requests. Allowed values:LOW,MEDIUM,HIGH. Defaultvalue:MEDIUM.
  • TAG (optional):request tagto help identify exporter traffic in Spanner monitoring.Default value:bq_export.

Export query requirements

To export query results to Spanner, the results must meet thefollowing requirements:

  • All columns in the result set must exist in the destination table, and theirtypes must match or beconvertible.
  • The result set must contain allNOT NULL columns for the destination table.
  • Column values must not exceed Spannerdata size limits within tables.
  • Any unsupported column types must be converted to one of the supported typesbefore exporting to Spanner.

Type conversions

For ease of use, Spanner exporter automatically applies thefollowing type conversions:

BigQuery typeSpanner type
BIGNUMERICNUMERIC (PostgreSQL dialect only)
FLOAT64FLOAT32
BYTESPROTO
INT64ENUM

Export data

You can use theEXPORT DATA statementto export data from a BigQuery table into aSpanner table.

The following example exports selected fields from a table that's namedmydataset.table1:

EXPORTDATAOPTIONS(uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",format='CLOUD_SPANNER',spanner_options="""{ "table": "TABLE_NAME" }""")ASSELECT*FROMmydataset.table1;

Replace the following:

  • PROJECT_ID: the name of your Google Cloud project
  • INSTANCE_ID: the name of your database instance
  • DATABASE_ID: the name of your database
  • TABLE_NAME: the name of an existing destination table

Export multiple results with the samerowkey value

When you export a result containing multiple rows with the samerowkey value,values written to Spanner end up in the sameSpanner row. Only single matching BigQuery row(there is no guarantee which one) will be present in the Spannerrow set produced by export.

Export continuously

Preview

This feature is subject to the "Pre-GA Offerings Terms" in the General Service Terms section of theService Specific Terms. Pre-GA features are available "as is" and might have limited support. For more information, see thelaunch stage descriptions.

To continuously process an export query, seeCreate continuous queries for instructionsandexample code.

Export optimization

To optimize the export of records from BigQuery toSpanner, you can try the following:

Pricing

When you export data to Spanner using theEXPORT DATA statement,you are billed usingBigQuery capacity compute pricing.

To export continuously to Spanner using a continuous query, youmust have aBigQuery Enterprise or Enterprise Plus editionslot reservation and areservation assignmentthat uses theCONTINUOUS job type.

BigQuery exports to Spanner that cross regionalboundaries are charged using data extraction rates. For more information, seeBigQuery pricing.To avoid data transfer charges, make sure that your BigQueryexport runs in the same region as the Spannerdefault leader. Continuousquery exports don't support exports that cross regional boundaries.

After the data is exported, you're charged for storing the data inSpanner. For more information,seeSpanner pricing.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.