Connecting your warehouse
How to connect PostgreSQL, BigQuery, Snowflake, Redshift, MySQL, and other warehouses to Celiq.
Celiq connects directly to your data warehouse. All queries run against your live data โ Celiq never copies or caches your raw tables. You stay in control of your data.
Supported warehouses
| Warehouse | Status |
|---|---|
| PostgreSQL | Generally available |
| Google BigQuery | Generally available |
| Snowflake | Generally available |
| Amazon Redshift | Generally available |
| MySQL / MariaDB | Generally available |
| Microsoft SQL Server | Generally available |
| Databricks | Generally available |
| ClickHouse | Generally available |
| DuckDB | Generally available |
To connect a warehouse, navigate to Admin โ Connections โ New connection and select your warehouse type.
PostgreSQL
Required:- Host (e.g.
db.example.com) - Port (default: 5432)
- Database name
- Username and password
SELECT on the schemas you want Celiq to query.
CREATE USER celiq_reader WITH PASSWORD 'your_password';
GRANT CONNECT ON DATABASE your_database TO celiq_reader;
GRANT USAGE ON SCHEMA public TO celiq_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO celiq_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO celiq_reader;BigQuery
Two projects, one connection
BigQuery has two different project IDs that serve different purposes. Mixing them up is the most common misconfiguration:
| Field | What it is | Example |
|---|---|---|
| Data Project ID | The project that owns your dataset โ where the data lives | bigquery-public-data |
| Billing project | The project where query costs are charged โ from your service account JSON | my-company-gcp |
The Data Project ID field in Celiq is always the project that owns the dataset. Your service account's project_id in the JSON key file is your billing project โ these are often different.
project_id is the data project. It is not โ it is your billing project. Enter the data project manually in the Data Project ID field.
How to find your data project: BigQuery console โ click your dataset โ Details tab โ Project.
Your full table path will be: {Data Project ID}.{dataset}.{table_name}
For example: bigquery-public-data.thelook_ecommerce.orders
The connection form shows a live preview of this path as you type, so you can verify it looks correct before saving.
Required IAM roles
Grant the Celiq service account both of these roles on the relevant project:
- BigQuery Data Viewer โ read table data and schema
- BigQuery Job User โ run query jobs
If your data lives in a different project than your billing project (common when querying bigquery-public-data or a shared dataset), also grant BigQuery Data Viewer on the data project.
Dataset location
Celiq automatically detects your dataset's region. You do not need to specify a location โ just the project ID and dataset name. Celiq reads the location from the dataset metadata and routes queries to the correct region.
If your dataset is in a non-default region (e.g. EU, us-central1), Celiq handles this transparently.
Service account setup
- Open GCP IAM and create a new service account.
- Grant the two IAM roles above.
- Under Keys, click Add key โ Create new key โ JSON.
- Download the JSON key file.
- In Celiq, open Admin โ Connections โ New connection โ BigQuery.
- Paste the entire contents of the JSON key file into the Service account JSON field.
- Enter your Billing project ID (the project that query costs are charged to).
- Enter your Default dataset โ the BigQuery dataset Celiq will query by default (e.g.
thelook_ecommerce).
Cross-project datasets
If your data lives in a different project than where you are billed:
- Billing project โ the project ID where query costs are charged. Usually the same project as your service account.
- Dataset project โ the project where your data actually lives (enter this in the Data project ID field).
Celiq will use the billing project for query execution but reference tables in the data project using fully qualified names (data_project.dataset.table).
Snowflake
Required:- Account identifier (e.g.
xy12345.us-east-1) - Warehouse (compute cluster)
- Database
- Schema
- Username and password (or key-pair authentication)
SELECT privileges and assign it a dedicated warehouse to avoid contending with production workloads.
Amazon Redshift
Required:- Host (cluster endpoint)
- Port (default: 5439)
- Database name
- Username and password
Firewall and IP allowlisting
If your warehouse requires IP allowlisting, contact support@celiq.co for the current list of Celiq egress IP addresses. These are static and do not change without notice.
Testing your connection
After filling in the connection form, click Test connection. Celiq will:
- Attempt to open a connection to your warehouse
- Run
SELECT 1to verify read access - Read the schema of the default database/dataset
A green tick means the connection is working. If the test fails, the error message will tell you exactly what went wrong โ authentication failure, network timeout, missing permissions, etc.
Synced connectors
Some data sources sync to your warehouse daily rather than being queried directly. Configure the sync in Admin โ Connectors.
| Connector | Sync frequency | Notes |
|---|---|---|
| Shopify | Daily at 2am UTC | Orders, products, customers, refunds |
| Stripe | Daily at 2am UTC | Payments, subscriptions, refunds |
| Google Analytics 4 | Daily at 3am UTC | Sessions, events, conversions |
Once synced, data appears as a regular table in your warehouse and can be modelled with Forge like any other source.
Table reference formats
How you write physical_table in a node depends on your warehouse. Using the wrong format is the most common cause of "table not found" errors.
| Warehouse | Table reference format | Example |
|---|---|---|
| BigQuery | table or dataset.table | orders or ecommerce.orders |
| Snowflake | TABLE or SCHEMA.TABLE | ORDERS or PUBLIC.ORDERS |
| PostgreSQL | schema.table | public.orders |
| Redshift | schema.table | public.orders |
| MySQL | table (no database prefix) | orders |
| PlanetScale | table (no database prefix) | orders |
| Databricks | catalog.schema.table | main.default.orders |
public. prefix โ BigQuery has no concept of a public schema. The dataset.table form is only needed when querying across datasets.
Snowflake: Identifiers are case-insensitive by default. Celiq normalises unquoted identifiers to uppercase. Use SCHEMA.TABLE for cross-schema references.
PostgreSQL / Redshift: If you enter a bare table name without a schema, Celiq adds the public. prefix automatically.
MySQL / PlanetScale: Table references have no database prefix โ just the table name.
Databricks: Always use a fully-qualified catalog.schema.table path.
Row-level security
Celiq enforces row-level security through Data Keys โ defined in your node CML and enforced on every query.
What it is: A filter that always applies to a node's queries, regardless of what the user asks. Users cannot remove it. Where to define it: In your node CML:node: orders
table: orders
data_key:
field: workspace_id
value: "{{ current_workspace_id }}"Field-level security (Data Gates)
Data Gates hide fields from specific roles.
Where to define it: In your node CML:fields:
- name: salary
type: decimal
data_gate: finance_only[RESTRICTED], Lens has fields hidden entirely, Weaver/Luminary have full access.
Connection credentials are encrypted at rest
Celiq encrypts all warehouse credentials using AES-256 before storing them. The encryption key is environment-specific and never logged. Credentials are decrypted only at query time, in memory, and are never written to disk or included in logs.
Data quality checks per warehouse
Before Orion returns a number โ and before a mosaic tile renders a KPI โ Celiq runs a data quality check: is the underlying data fresh, and is it complete? How that freshness check is performed depends on your warehouse, because each engine exposes table metadata differently.
How freshness is determined
Celiq establishes "how recent is this data?" using, in order of preference:
- The result's own date column โ the most recent value of the date dimension in the query result. This works on every warehouse and is the primary signal.
- Table metadata โ the warehouse's recorded last-modified time for the source table, used as a corroborating signal where available.
The completeness check (row-count anomaly detection) compares the current run against the previous run and is identical across all warehouses.
Behaviour by warehouse
| Warehouse | Table-metadata freshness | Notes |
|---|---|---|
| PostgreSQL | Partial | No reliable per-table modified timestamp; freshness uses the result's date column. |
| BigQuery | Available, with caveats | last_modified_time is available but coarse โ see below. |
| Snowflake | Available | Uses table metadata (LAST_ALTERED) plus the result's date column. |
| Amazon Redshift | Partial | Relies on the result's date column; metadata timestamps are unreliable. |
| MySQL / MariaDB | Partial | information_schema update times are storage-engine dependent; date column is primary. |
| Microsoft SQL Server | Available | Uses table metadata plus the result's date column. |
| Databricks | Available | Reads table history metadata where Delta history is enabled. |
| ClickHouse | Partial | Freshness uses the result's date column. |
| DuckDB | Result column only | No persistent table-modified metadata; freshness uses the result's date column. |
In all cases, when table metadata is unavailable or unreliable, Celiq falls back to the most recent date in the query result โ so freshness checking works everywhere, just with less corroboration on some engines.
BigQuery freshness check limitations
BigQuery exposes a table's last_modified_time, but it has limitations Celiq has to work around:
- It is coarse.
last_modified_timeupdates when the table is written, not necessarily when the data period you are querying completes. A daily-partitioned table can show a recent modified time while the partition for "today" is still filling. - Streaming inserts lag. Tables fed by the streaming buffer can report a modified time that trails the actual most recent rows by a few minutes.
- Views and wildcard tables. Freshness metadata is not meaningful for views or
*-wildcard table queries; Celiq uses the result's date column instead.
Because of this, on BigQuery, Celiq treats the most recent date in the query result as the authoritative freshness signal and uses last_modified_time only as a secondary check. If a BigQuery tile shows an unexpected โ ๏ธ stale indicator, confirm that the date dimension in the reveal points at the column that actually advances with each load (e.g. the partition column), not a static created-at field.
The data quality check never blocks a query. A โ ๏ธ indicator is a caution โ the number still renders. See Data quality checks for how freshness states and confidence levels are presented.