HOW-TO ยท DATA SYNC

Get a Google Sheet into BigQuery without Apps Script.

By Chris Davidson, founder of yForest · Updated September 26, 2026

A manually updated spend sheet, mapped into BigQuery with Upsert, so a correction updates a row instead of duplicating it.

Start 14-day free trial Download on theMac App Store

No credit card. 14 days. Cancel in one click.

macOS 15+ · Apple Silicon native · 14-day free trial · No credit card

Quick answer: Add Google Sheets and BigQuery as connections, open Pipelines, Build, New Sync, and map the sheet's columns to a BigQuery table. Use Upsert with a real unique key if the sheet gets edited in place, not just appended to, then save it as a scheduled job. Pipelines tier.

Before you start

A Google Sheets connection added under Databases, pointed at the sheet you want to pull from, and a working BigQuery connection as the target. Pipelines tier.

Steps

  1. Add a Google Sheets connection under Databases, pointed at the sheet, and confirm you have a working BigQuery connection.
  2. Open Pipelines โ†’ Build and click New Sync.
  3. On the left, pick the Google Sheets connection and the sheet or range as the source.
  4. On the right, pick the BigQuery connection and the Target Table.
  5. Drag fields across, or click AI Map, then pick a MODE.
  6. Click Dry Run to preview, then Save it as a scheduled job.

A worked example

A marketing team keeps a manual spend sheet with columns campaign, channel, date, and spend, updated by hand a few times a week. Map those four columns to a BigQuery target:

Target table: `my-gcp-project.marketing.campaign_spend`
Columns: campaign, channel, date, spend

Because rows in the sheet sometimes get corrected after the fact rather than only appended, set MODE to Upsert and choose a combination like campaign + date + channel as MATCH ON, assuming that combination is unique per row. QueryFlow handles the MERGE into BigQuery on those key columns; a corrected spend number updates the existing row instead of creating a duplicate. Save it as a job running nightly, after the team's usual end-of-day update to the sheet.

Why Upsert, not a plain Insert

A manually maintained sheet gets edited in place more often than a system-generated export does. Insert alone would just pile up a new row every run even when nothing actually changed, or worse, duplicate a row that was only corrected. Upsert with a real unique key avoids both.

Naming the target so it's obvious later

A table named sheet_import tells nobody what's in it six months from now. Name the target for what it holds, marketing.campaign_spend, and name the sync itself the same way, "Marketing spend sheet to BigQuery," so it's identifiable in the Pipelines list without opening it to check.

A default dataset makes the mapping step faster

If most of what you sync from sheets lands in the same BigQuery dataset, set that dataset as the connection's Default Dataset when you add it. The Target Table field then only needs the table name, campaign_spend, rather than the fully qualified path every time you build a new sync against the same destination.

Check it worked

Run Dry Run first and check the preview against what the sheet currently shows. After a real run, check the job's history: a clean run reports rows synced with no errors.

Troubleshooting

If you seeFix
No BigQuery connections availableAdd a BigQuery connection under Databases first, see the BigQuery connect tutorial.
Duplicate key values in sourceThe MATCH ON combination you picked isn't actually unique per row in the sheet. Add another column to the key, or clean up the sheet.
Type mismatch on spend or dateA spreadsheet stores everything as text or a loosely typed number by default; check the target column's type matches what the sheet is actually sending.
A blank row in the sheet breaks the runA stray blank row past your data range gets read as a row of nulls. Tighten the source range to exclude it.

What this doesn't do

It doesn't watch the sheet for a live edit and sync that instant, it's a scheduled job, so plan the interval around how often the sheet actually changes, not how anxious you feel about it.

Why this beats exporting the sheet by hand

The alternative most teams actually do today is exporting the sheet to CSV and loading that manually, or writing a small Apps Script that pushes rows out on a timer. Both work, but both are one more thing to remember or one more script to keep running. A Data Sync job lives next to your other scheduled jobs in QueryFlow, shows up in the same run history, and needs nothing installed inside the spreadsheet itself.

Extending the same pattern to other sheets

Once one sheet-to-BigQuery sync is working, the same mapping pattern, Sheets connection as source, a MATCH ON that's actually unique, Upsert for anything hand-edited, carries over to any other manually maintained sheet worth getting into the warehouse: a headcount tracker, a vendor list, a manually curated exceptions list a report needs to join against.

Related syncs

See also: Integrations Load a CSV into BigQuery on Mac Sync Databricks to BigQuery.

Integrations Load a CSV into BigQuery on Mac Sync Databricks to BigQuery
QueryFlow Studio $9.99/mo · $99/yr
QueryFlow Pipelines $29.99/mo · $199.99/yr

Frequently asked

Do I need Apps Script for this?

No. Data Sync reads the sheet directly through QueryFlow's Google Sheets connection; there's no script to write, deploy, or debug inside the spreadsheet.

What happens if someone edits the sheet in place instead of adding rows?

Insert alone would just add duplicate rows every run. If the sheet gets edited rather than appended to, use Upsert with a MATCH ON column that uniquely identifies each row, a campaign ID or a date-plus-channel combination.

Does this sync instantly when the sheet changes?

No, it's a scheduled sync, not a live watch on the sheet. It runs on whatever cadence you set, hourly, nightly, or on demand from Build.

Which tier includes this?

Data Sync is a Pipelines feature. Studio covers connecting to and querying both Google Sheets and BigQuery, but not building a sync between them.

Stop copy-pasting the spend sheet.

14-day free trial, no card. Map it once, sync it nightly.

Start 14-day free trial

No credit card. 14 days. Cancel in one click.