Pricing

Snowflake to Google Sheets: Why the Official Connector Only Goes One Way (and How to Get Data OUT)

sheets.google.com — Snowflake revenue importLiveFileEditViewInsertFormatDataToolsA1fxABCD1regionrevenueorderstrend23456US East$4.2M12,841+14%EU West$2.9M8,204+8%APAC$1.7M5,112-3%US West$1.4M4,390+2%LATAM$880K2,901-11%Snowflake dataSheet2Synced via BrookedBrookedSnowflakeChoose tableSearch tables…REVENUE_BY_REGIONCUSTOMER_EVENTSPRODUCT_METRICSUSER_SESSIONSNext →Filter rowsNarrow results before importREGION=US EastDATE2025-01-01+ Add filter← BackNext →Sort resultsOrder rows before importrevenue↓ Desc+ Add sort← BackNext →Importing…Importing from Snowflake…5 rows · 3 columns✓ Import complete — 5 rows added← BackNext →Schedule refreshKeep your sheet in sync automaticallyManualHourlyDaily9:00 AMWeeklyDone ✓
JW
James Whitfield

The Snowflake Openflow connector pushes data INTO Snowflake, not out. Learn the exact grants, workarounds, and tools you need to get Snowflake query results into Google Sheets reliably.

The Snowflake official connector for Google Sheets (Openflow) only moves data one direction: FROM your spreadsheet INTO Snowflake. If you opened it expecting to pull query results into Sheets, you are not doing it wrong. The tool simply does not do that.

This guide explains why that limitation exists, what breaks when people try to force it, and the three methods that actually work for getting data out of Snowflake and into Google Sheets.

Why the Official Connector Won't Pull Data Out

Snowflake's official Google Sheets integration is called Openflow. It was built specifically for the data ingestion use case: a business analyst pastes data into a Google Sheet and Openflow loads it into a Snowflake table automatically. That is genuinely useful, but it is one-directional by design.

The confusion is understandable. The integration is listed under Snowflake's partner ecosystem and branded with both logos, so people assume it handles the full round-trip. It does not.

Snowflake has acknowledged this in community forum threads dating back to 2021. There is no roadmap date for adding an outbound query feature to Openflow. The product team's stated position is that data export belongs to BI tools, not a Sheets integration.

This means every team that needs to answer the question "how do I get Snowflake data into Google Sheets?" has to find their own solution. There are three broad categories, and each has real trade-offs.

The Six Problems That Bite Everyone

Before covering the methods, it is worth naming the six specific pain points that make this problem harder than it looks.

1. Warehouse Auto-Suspend Causing Intermittent Failures

Snowflake warehouses suspend after a configurable idle period (default is typically 10 minutes). When a connector or script tries to run a query against a suspended warehouse, there is a cold start delay of 10–30 seconds. Most connectors handle this gracefully, but home-built Python scripts often time out at exactly this moment, causing intermittent failures that look like network errors.

Fix: set AUTO_SUSPEND = 300 (five minutes) on the warehouse used for reporting, or configure your connection to increase the statement timeout to at least 60 seconds.

2. Account Identifier Format Confusion

Snowflake supports two account identifier formats and they are not interchangeable.

  • Legacy locator format: xy12345.us-east-1 (region included)
  • Organization-account format: myorg-myaccount (no region)

Most documentation examples use the legacy format. Most newer accounts default to the org-account format. If you paste your account URL into a connector and it rejects it, try the other format. You can find both identifiers in Snowflake under Admin > Accounts.

3. RBAC Permission Complexity (Six GRANTs Required)

Snowflake's role-based access control is powerful but verbose. A service account used by a connector needs six separate grants to query a table and write results. Missing any one of them produces a permission error that does not always tell you which grant is absent. The exact statements are in the section below.

4. Credit Cost Anxiety Around Scheduled Refresh

Teams with strict Snowflake credit budgets often hesitate to set up scheduled refreshes because they are not sure how much each query run costs. A simple SELECT query against a small table on an X-Small warehouse costs roughly 0.0003 credits per second of execution time. A query that runs for two seconds, scheduled every 15 minutes, costs less than $0.05 per month at standard list pricing. In almost every practical case the cost is negligible, but the anxiety is real and worth naming.

5. OAuth Token Expiry Causing Silent Stale Data

If you connect a third-party tool to Snowflake using OAuth, the access token expires on a schedule (typically 90 days, configurable by your Snowflake admin). After expiry, the connector stops refreshing but may not surface an error in the sheet itself. The data just sits there, stale, looking current. Always check the connector's status dashboard or set up an alert on refresh failures.

6. The Three Painful Workarounds People Fall Back On

Before finding a real solution, most teams cycle through three ad hoc approaches:

  • The CSV Shuffle: Export a CSV from Snowflake UI, upload to Drive, open in Sheets. Works once. Falls apart the second time someone forgets to delete the old file.
  • The Ticket Queue: Ask the data team for a Sheets export. Creates a bottleneck and a support queue. Data is stale by the time the ticket is resolved.
  • The Fragile Python Script: Someone writes a script, it works, they leave the company, nobody can maintain it. The script breaks silently when a warehouse is renamed or a credential rotates.

Method 1: CSV Download (Manual)

This works and requires no setup. It is not repeatable, but it is the right answer for a one-time export.

Steps:

  1. Log in to the Snowflake web interface (Snowsight).
  2. Open a new worksheet and write your query.
  3. Run the query. Results appear in the results pane below.
  4. Click the download icon in the top-right corner of the results pane.
  5. Choose CSV format.
  6. Open Google Sheets, go to File > Import, and upload the CSV.

Limitations: This is a point-in-time snapshot. There is no scheduled refresh, no version history, and no connection between the sheet and Snowflake. As soon as the underlying data changes, the sheet is out of date.

Use this method for: one-time data pulls, ad hoc analysis, sharing a snapshot with someone who does not need live data.

Method 2: Python Script with snowflake-connector-python and gspread

For teams comfortable with Python, this approach gives full control. It runs on a schedule using cron, GitHub Actions, or a simple cloud function.

Prerequisites:

  • A Snowflake service account with the grants listed below
  • A Google Cloud service account with the Google Sheets API and Google Drive API enabled
  • Python 3.9 or later

Install dependencies:

Code
pip install snowflake-connector-python gspread google-auth

The script:

python
import snowflake.connector
import gspread
from google.oauth2.service_account import Credentials

# Snowflake connection
conn = snowflake.connector.connect(
    user="SHEETS_SERVICE_USER",
    password="your_password",           # use env var in production
    account="myorg-myaccount",          # or legacy locator format
    warehouse="REPORTING_WH",
    database="ANALYTICS",
    schema="PUBLIC",
    login_timeout=60,                   # handles auto-suspend cold start
    network_timeout=120
)

cursor = conn.cursor()
cursor.execute("SELECT * FROM reporting.daily_summary LIMIT 10000")
rows = cursor.fetchall()
headers = [col[0] for col in cursor.description]
cursor.close()
conn.close()

# Google Sheets connection
scopes = [
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/drive"
]
creds = Credentials.from_service_account_file("service_account.json", scopes=scopes)
gc = gspread.authorize(creds)

sheet = gc.open_by_key("your_spreadsheet_id").sheet1
sheet.clear()
sheet.append_row(headers)
sheet.append_rows(rows)

print(f"Wrote {len(rows)} rows to Google Sheets.")

Key details:

  • Set login_timeout=60 to handle warehouse auto-suspend without failing.
  • Use environment variables for credentials, not hardcoded strings.
  • sheet.clear() before writing prevents duplicate rows on repeated runs.
  • For large result sets (over 50,000 rows), batch the append_rows calls in chunks of 1,000 to avoid Google Sheets API rate limits.

Scheduling with GitHub Actions (free):

Create a workflow file at .github/workflows/snowflake-sync.yml with a cron trigger. Store your Snowflake password and Google service account JSON as GitHub Secrets. This gives you a scheduled sync with zero infrastructure cost.

Limitations: Requires Python knowledge to set up and maintain. Breaks when credentials rotate unless you have a process for updating secrets. Not self-healing.

Method 3: Third-Party Connectors

For teams that need a no-code, scheduled, maintained solution, third-party connectors are the practical answer. Several products handle this use case.

brooked.io is built specifically for pulling data from data warehouses and APIs into Google Sheets on a schedule. You connect your Snowflake account once (using the service account credentials and grants below), write or paste a SQL query, and set a refresh schedule. The sheet stays current automatically. It handles warehouse auto-suspend, token refresh, and permission errors with clear status messages rather than silent stale data.

Coefficient is a Google Sheets add-on that supports Snowflake as a source. It has a point-and-click query builder and scheduled refresh. The free tier has row limits.

Hightouch is designed for reverse ETL: moving data from warehouses to business tools. It supports Snowflake to Google Sheets but is primarily built for syncing to CRMs and ad platforms. It is more setup than most analytics teams need for a simple Sheets export.

Weld combines a SQL editor with connectors to Google Sheets. It supports Snowflake and has a visual query builder. It is a good fit for teams that want a lightweight dbt-adjacent workflow.

Exact GRANT Statements for a Service Account

Whether you are using a Python script or a third-party connector, you need a Snowflake service account with the correct permissions. The following six GRANT statements cover the minimum required access.

Run these as a SYSADMIN or SECURITYADMIN in a Snowflake worksheet, substituting your actual warehouse, database, schema, and role names:

sql
-- 1. Create the role
CREATE ROLE IF NOT EXISTS SHEETS_CONNECTOR_ROLE;

-- 2. Grant warehouse usage (required to execute queries)
GRANT USAGE ON WAREHOUSE REPORTING_WH TO ROLE SHEETS_CONNECTOR_ROLE;

-- 3. Grant database usage (required to see the database)
GRANT USAGE ON DATABASE ANALYTICS TO ROLE SHEETS_CONNECTOR_ROLE;

-- 4. Grant schema usage (required to see tables in the schema)
GRANT USAGE ON SCHEMA ANALYTICS.PUBLIC TO ROLE SHEETS_CONNECTOR_ROLE;

-- 5. Grant SELECT on specific table (principle of least privilege)
GRANT SELECT ON TABLE ANALYTICS.PUBLIC.DAILY_SUMMARY TO ROLE SHEETS_CONNECTOR_ROLE;
-- Or grant SELECT on all current and future tables in the schema:
-- GRANT SELECT ON ALL TABLES IN SCHEMA ANALYTICS.PUBLIC TO ROLE SHEETS_CONNECTOR_ROLE;
-- GRANT SELECT ON FUTURE TABLES IN SCHEMA ANALYTICS.PUBLIC TO ROLE SHEETS_CONNECTOR_ROLE;

-- 6. Assign the role to the service account user
GRANT ROLE SHEETS_CONNECTOR_ROLE TO USER SHEETS_SERVICE_USER;

After running these grants, log in as SHEETS_SERVICE_USER and run a test SELECT to confirm access before configuring any connector.

Comparison Table

MethodSetup TimeTechnical Skill RequiredOngoing MaintenanceScheduled RefreshCost
CSV Download (Manual)2 minutesNoneNoneNoFree
Python Script2–4 hoursPython, API authMedium (credential rotation)Yes (DIY)Free + infra
brooked.io10–15 minutesNoneNoneYes (built-in)Paid
Coefficient15–30 minutesLowLowYes (built-in)Free tier + paid
Hightouch30–60 minutesMediumLowYes (built-in)Paid
Weld20–30 minutesLowLowYes (built-in)Paid

Troubleshooting Common Errors

"SQL access control error: Insufficient privileges to operate on table" You are missing Grant 4 or Grant 5 above. Run SHOW GRANTS TO USER SHEETS_SERVICE_USER to see what is currently assigned, then compare against the six grants above.

"Account must be specified" or "Invalid account identifier" Try switching between the legacy locator format (xy12345.us-east-1) and the org-account format (myorg-myaccount). Find both in Snowflake under Admin > Accounts.

Connection times out on first attempt, works on retry The warehouse is auto-suspending. Increase your connection timeout to 60 seconds or more. Alternatively, set AUTO_RESUME = TRUE on the warehouse and increase LOGIN_TIMEOUT in the connector settings.

OAuth token expired, data is stale with no error The access token has expired (typically after 90 days). Re-authenticate in the connector's settings. Set up a calendar reminder or an alert on refresh failures to catch this before it causes problems.

Python script writes duplicate rows You are calling append_rows without clearing the sheet first. Add sheet.clear() before writing. If you need to preserve formulas in other columns, use sheet.update('A1', [headers] + rows) with the exact cell range instead.

Google Sheets API quota exceeded (429 error) You are writing too many rows in a single API call. Batch your append_rows calls in chunks of 1,000 rows with a short sleep between batches.

Bottom Line

The Snowflake Openflow connector is a one-way street into Snowflake, not out of it. For a true Snowflake to Google Sheets connection, you have three realistic options: a manual CSV export (fine for one-off pulls), a Python script (flexible but requires maintenance), or a dedicated connector like brooked.io (the lowest-maintenance path for scheduled, reliable refreshes).

Whichever method you choose, run the six GRANT statements above for your service account first. They are the most common source of failed connections and hours of debugging.

Get Your Snowflake Data Into Google Sheets in 15 Minutes

brooked.io connects directly to Snowflake, runs your SQL on a schedule, and writes results into Google Sheets automatically. No Python required. No stale data. No silent failures.

Start your free trial at brooked.io and have live Snowflake data in your spreadsheet before your next meeting.

Frequently asked questions

Does Snowflake have a native Google Sheets export feature?

Not as of mid-2026. Snowsight (the Snowflake web interface) lets you download query results as a CSV, which you can then import into Google Sheets manually. There is no built-in scheduled export or direct Sheets integration for outbound data.

How much does it cost to run queries for a Sheets refresh?

At standard Snowflake list pricing, an X-Small warehouse costs about $2 per credit. A query that runs for two seconds uses roughly 0.0006 credits. A refresh running every 15 minutes would cost less than $0.10 per month for most typical reporting queries. The cost is almost always negligible compared to the engineering time of managing a manual process.

Can I use Snowflake's Data Sharing feature to connect to Google Sheets?

Data Sharing is designed for sharing data between Snowflake accounts, not for exporting to external tools like Google Sheets. You would still need a connector or script to read from the shared data and write to Sheets.

What is the row limit for Google Sheets?

Google Sheets supports a maximum of 10 million cells per spreadsheet, and a single sheet has a maximum of 10 million cells. For most reporting use cases this is not a constraint, but if you are pulling large datasets, add a LIMIT clause to your Snowflake query and consider whether a BI tool is a better fit.

Is a Python script secure for storing Snowflake credentials?

Only if you use environment variables or a secrets manager (AWS Secrets Manager, GitHub Secrets, Doppler, etc.) rather than hardcoding credentials in the script file. Never commit a credentials file to a git repository.

How do I know if my Snowflake data in Google Sheets is stale?

Add a timestamp column to your SELECT query using CURRENT_TIMESTAMP() aliased as last_refreshed. This writes the time the query ran into the sheet, giving readers a clear indicator of data freshness.

Ready to connect your data to Google Sheets?

Brooked's free tier covers 100 imports per month with AI Analyst included, no credit card required.

Install Brooked free →

Also in Data Warehouse

More Data Warehouse guides

Data Warehouse

How to Connect Snowflake to Google Sheets

A step-by-step guide to importing Snowflake query results into Google Sheets, scheduling auto-refresh, and writing data back to Snowflake, using Brooked.

JW
James Whitfield
Read
Data Warehouse

How to Connect Databricks to Google Sheets

The official Databricks Connector setup walked from end to end, SQL warehouse selection, Unity Catalog permissions for scheduled refresh, the IP access list gotcha, and the limits table (15-min timeout, 10M cells, 20 schedules), plus Python and no-code alternatives.

JW
James Whitfield
Read

Get your spreadsheet hours back

Brooked sets up in seconds. Your team is querying live data before lunch.

Get started free