Connect PostgreSQL to Google Sheets

Read a table or a custom query from any reachable Postgres database, or load transformed data into one (append, replace, or upsert). Ideal for lightweight warehousing and moving data between systems.

What you can pull from PostgreSQL

A PostgreSQL job pulls records into a flat table on your schedule. Nested fields are flattened into ordinary columns, so what lands in Google Sheets is ready to sort, filter and total rather than needing another cleanup step.

  • Table or custom SQL
  • Append / replace / upsert
  • Any reachable host

Options you can set

table
Read a whole table
query
Or run SQL instead. One statement only - multi-statement queries are rejected
limit
Cap the rows a run reads

How it lands in Google Sheets

Google Sheets accepts append and overwrite writes. Overwrite replaces the target range, which suits a snapshot; append adds rows underneath, which suits a log you are accumulating. There is no upsert here, so rows are added or replaced rather than merged.

  • Append adds rows below existing content; overwrite replaces the target range.
  • No upsert: a spreadsheet has no primary key, so there is nothing to merge on. Use Airtable or Postgres if rows must be updated in place.
  • Google caps a spreadsheet at 10 million cells across all tabs. Filter before writing rather than after.

Authentication

PostgreSQL authenticates with ordinary database credentials, stored encrypted. A read-only user is enough, because this connector only ever reads.

Keeping runs incremental

Yes. Use a query with a WHERE clause on your updated-at column so each run reads only what changed.

Because Google Sheets has no upsert, decide what a re-run should mean before you schedule it. Overwrite keeps a current snapshot; append accumulates history and will grow without bound.

A worked example

A query result, refreshed each morning

Point the source at a query rather than a table, aggregate in SQL, and write the small result with overwrite. The database does the work it is good at and the sheet stays small enough to open.

Schedule: 0 7 * * 1-5read it back in plain English

Common gotchas

Most of what goes wrong with a scheduled sync is not a bug — it is a detail of how one side behaves that nobody wrote down. These are the ones that come up for this pair.

Set either table or query, never both

The config rejects both being set, and rejects neither - caught when the job is saved rather than on its first run.

An open-ended range beats a padded one

Writing to A2:D is better than A2:D1000 for appends: the padded form reserves rows you may not need and makes the append boundary ambiguous.

Aggregate in SQL, not in the sheet

A spreadsheet caps at 10 million cells across all tabs. Writing a raw table and pivoting afterwards is how people hit that; a GROUP BY in the query avoids it entirely.

Set it up in four steps

  1. 1

    Connect PostgreSQL

    Host, port, database, user and password, stored encrypted.

  2. 2

    Connect Google Sheets

    Connect your Google account once. Paste a spreadsheet URL or ID.

  3. 3

    Shape the data

    Select the columns you want, filter rows, cast types and add computed fields. Everything else is dropped before it reaches the destination.

  4. 4

    Schedule it

    Run once, or on a cron. Every run refreshes Google Sheets with the latest PostgreSQL data.

Do I need an add-on or extension for this?

No. The job runs server-side and writes into Google Sheets through its API, so there is nothing installed in the spreadsheet itself. It keeps running when nobody has the file open, and a copy of the file does not need anything installed to work.

How often does the data refresh?

On whatever schedule you set with a cron expression — hourly, daily, or a specific time on specific days. Each run pulls the latest from PostgreSQL.

Do I need to write any code?

No. You connect both sides, map the fields in a wizard and set a schedule. Computed fields accept small expressions — abs, round, min, max, len — but there is nothing to host or maintain.

Can I run my own SQL rather than reading a table?

Yes. Set a query instead of a table and aggregate in the database, which is usually far cheaper than moving raw rows and aggregating downstream. One statement only - multi-statement queries are rejected.

Does it need a superuser?

No. A user with SELECT on what you are reading is enough for a source; a destination needs INSERT and, for upsert, UPDATE on the target table.

Do I have to give access to my whole Google Drive?

No. Only the spreadsheets scope is requested. The Drive scope that most spreadsheet tools ask for is a restricted scope granting read access to every file you own; it is deliberately not requested here, which is why you paste a spreadsheet URL rather than browsing Drive.

Will this keep working if I copy the sheet?

The job writes to a specific spreadsheet ID, so a copy will not receive data until you point a job at it. Nothing is installed in the file itself, though, so copying never breaks the original.

Is the PostgreSQL connector free to use?

You can connect PostgreSQL and start syncing on the free plan.