Add Warehouse Adapter
Adds a new warehouse connection adapter to the Lightdash codebase across its common types, backend m
by lightdash · MIT
The skill
Adds a new warehouse connection adapter to the Lightdash codebase across its common types, backend migrations and services, warehouse client, frontend forms, CLI dbt target, and Dockerfile dbt adapter packages, using the Athena and DuckDB adapters as reference. Use when adding support for a new data warehouse type to Lightdash, such as a new database or query engine, or when wiring a new dbt adapter into Lightdash's packages and Docker image.
Add a Warehouse Adapter
Step-by-step checklist for adding a new warehouse connection to Lightdash. Follow the Athena adapter as the canonical example (PRs #19751/#19752). The MotherDuck/DuckDB adapter is the most recent implementation.
Layer 1: Common Types (packages/common/)
- [ ] Add entry to
WarehouseTypesenum insrc/types/projects.ts - [ ] Define
CreateXxxCredentialstype withtype: WarehouseTypes.XXXdiscriminant- Sensitive fields (tokens, passwords, keys) should be optional (
token?: string) — not required with empty-string sentinel
- Sensitive fields (tokens, passwords, keys) should be optional (
- [ ] Define
XxxCredentials = Omit<CreateXxxCredentials, SensitiveCredentialsFieldNames> - [ ] Add sensitive fields to
sensitiveCredentialsFieldNamesarray if not already present (tokens, passwords, keys) - [ ] Add
CreateXxxCredentialstoCreateWarehouseCredentialsunion - [ ] Add
XxxCredentialstoWarehouseCredentialsunion - [ ] Update
UserWarehouseCredentialsunion insrc/types/userWarehouseCredentials.ts - [ ] Update
UserWarehouseCredentialsWithSecretsunion - [ ] Add case to
getFieldQuoteChar()insrc/utils/warehouse.ts - [ ] Verify
getAggregatedField()insrc/utils/warehouse.tshandles the new adapter (may fall into existing case) - [ ] Check
src/utils/timeFrames.tsadapter config map has the new adapter - [ ] Check
src/compiler/translator.tsconvertTimezone()has the new adapter - [ ] Run:
pnpm -F common typecheck && pnpm -F common lint
Layer 2: Backend (packages/backend/)
Database Migration
- [ ] Create migration:
pnpm -F backend create-migration add_xxx_warehouse_type - [ ]
up: Insert{ warehouse_type: 'xxx' }intowarehouse_types - [ ]
down: Delete xxx credentials and type
Entity & Profile
- [ ] Add
'xxx'towarehouseTypesarray insrc/database/entities/warehouseCredentials.ts - [ ] Add case to
credentialsTarget()insrc/dbt/profiles.ts(beforedefault)- Pass secrets via
envVarReference()/envVar()pattern (not raw env var names or inline values) - Follow ClickHouse pattern:
password: envVarReference('password')in target,[envVar('password')]: credentials.passwordin environment
- Pass secrets via
- [ ] Verify
quoteCharsinsrc/dbt/DbtMetadataApiClient.tshas the adapter
Service Updates (exhaustive switch statements)
- [ ]
src/services/ProjectService/ProjectService.ts-clearSecretsFromCredentials()- Blank sensitive fields (
token: undefined) instead of destructuring + unsafeascast - Follow the same pattern as other warehouses (
{ ...credentials, password: '' })
- Blank sensitive fields (
- [ ]
src/services/ProjectService/ProjectService.ts- warehouse client creation switch - [ ]
src/services/ProjectService/ProjectService.ts- user credentials creation switch - [ ]
src/services/ProjectService/ProjectService.ts-getDatabaseFromWarehouseCredentials() - [ ]
src/models/UserWarehouseCredentials/UserWarehouseCredentialsModel.ts - [ ] Run:
pnpm -F backend typecheck && pnpm -F backend lint
Layer 3: Warehouse Client (packages/warehouses/)
- [ ] Create
src/warehouseClients/XxxWarehouseClient.ts- Extend
WarehouseBaseClient<CreateXxxCredentials> - Implement
XxxSqlBuilder extends WarehouseBaseSqlBuilder - Implement:
streamQuery(),getCatalog(),getAllTables(),getFields()(inheritedtest(),runQuery(),executeAsyncQuery()work via base class — don't add no-op overrides) - Pass credentials directly to client library (like ClickHouse/Databricks), never via
process.env - Use constructor
overridesparam for alternate construction (e.g. pre-aggregate) instead ofAnyTypecasts on readonly fields
- Extend
- [ ] Add case in
src/warehouseClientFromCredentials.tsfactory - [ ] Add case in
src/ssh/sshTunnel.ts(typically a no-opbreakfor cloud warehouses) - [ ] Export from
src/index.ts - [ ] Write tests in
src/warehouseClients/XxxWarehouseClient.test.ts - [ ] Run:
pnpm -F @lightdash/warehouses typecheck && pnpm -F @lightdash/warehouses test
Layer 4: Frontend (packages/frontend/)
Warehouse Form
- [ ] Create
src/components/ProjectConnection/WarehouseForms/XxxForm.tsx- Follow
AthenaForm.tsxpattern with Mantine v8 components - Export
XxxSchemaInputforDbtSettingsForm
- Follow
- [ ] Add SVG logo to
src/components/ProjectConnection/ProjectConnectFlow/Assets/
Registration
- [ ] Add defaults to
WarehouseForms/defaultValues.ts(XxxDefaultValues+ add towarehouseDefaultValues) - [ ] Add validators to
WarehouseForms/validators.ts - [ ] Register in
WarehouseSettingsForm.tsx(labels + forms maps) - [ ] Register in
DbtSettingsForm.tsx(schema input switch) - [ ] Register in
ProjectConnectFlow/utils.tsx(WarehouseTypeLabels array) - [ ] Register in
UserSettings/MyWarehouseConnectionsPanel/CreateCredentialsModal.tsx(defaultCredentials) - [ ] Register in
UserSettings/MyWarehouseConnectionsPanel/EditCredentialsModal.tsx(getCredentialsWithPlaceholders) - [ ] Register in
UserSettings/MyWarehouseConnectionsPanel/WarehouseFormInputs.tsx - [ ] Run:
pnpm -F frontend typecheck && pnpm -F frontend lint
Layer 5: CLI (packages/cli/)
- [ ] Create
src/dbt/targets/xxx.ts- Define
XxxTargettype matching dbt profile structure - Define
xxxSchema: JSONSchemaType<XxxTarget>for ajv validation - Export
convertXxxSchema()function
- Define
- [ ] Add
case 'xxx':insrc/dbt/profile.tswarehouseCredentialsFromDbtTarget() - [ ] Add mock credentials in
src/handlers/dbt/getWarehouseClient.tsgetMockCredentials()
Layer 6: Docker (Dockerfile)
- [ ] Add the dbt adapter pip package (
dbt-xxx) to dbt venvs 1.8+ in theDockerfile- The adapter package name is typically
dbt-xxx(e.g.,dbt-duckdb,dbt-athena) - Use unversioned
"dbt-xxx"if the adapter has its own version scheme, or"dbt-xxx~=X.Y.0"if it tracks dbt-core versions - Check PyPI for the package name and version compatibility
- Only add to dbt versions that support the adapter (1.8+, not older 1.4-1.7)
- Reference:
dbt-athenawas added from 1.9+,dbt-duckdbfrom 1.8+
- The adapter package name is typically
Layer 7: Demo Project Compatibility (examples/full-jaffle-shop-demo/)
- [ ] Update
dbt/data/seeds.ymlcolumn types for the new adapter (DuckDB doesn't supportjsonb,TIME, etc.) - [ ] Update SQL macros in
dbt/macros/that have warehouse-specific branches (e.g.quarter_end_date.sql,casts.sql) - [ ] Add a profile target in
profiles/profiles.ymlfor testing - [ ] Test:
dbt seed --target xxx && dbt run --target xxx
Post-Implementation
- [ ]
pnpm generate-api(regenerates routes.ts and swagger.json) - [ ]
pnpm generate:chart-as-code-schema - [ ]
pnpm check:chart-as-code-schema - [ ] Run full typecheck:
pnpm -F common typecheck && pnpm -F backend typecheck && pnpm -F frontend typecheck
Reference Files
| Layer | Key File | Purpose |
|---|---|---|
| Common | packages/common/src/types/projects.ts |
Types, sensitive fields, unions |
| Backend | packages/backend/src/dbt/profiles.ts |
dbt profile generation |
| Backend | packages/backend/src/database/entities/warehouseCredentials.ts |
DB entity |
| Warehouse | packages/warehouses/src/warehouseClientFromCredentials.ts |
Factory |
| Frontend | packages/frontend/src/components/ProjectConnection/WarehouseSettingsForm.tsx |
Form registration |
| CLI | packages/cli/src/dbt/profile.ts |
CLI target conversion |
| Docker | Dockerfile |
dbt adapter pip packages per version |
Canonical Examples
- Athena: PRs #19751/#19752 (first adapter added with this pattern)
- MotherDuck/DuckDB: Branch
02-23-feat_add_duckdb_warehouse_client_with_s3_support
Use this skill
Connect your agent to the Skill Store MCP server and ask for it by ref: lightdash/add-warehouse-adapter-97110527806.
Details
- Publisher
- lightdash
- Category
- Data & Analytics › Databases & SQL
- License
- MIT
- Updated
- 2026-10-19
References
More from lightdash
- Add Onboarding Tour Add a first-run guided tour, product walkthrough, coachmarks, or empty-state mock/example data to…
- Add Scope Walkthrough Add a generated in-product walkthrough (a training module) for a permission scope, e.g.
- Agent Harness Guide for AI agents running in the isolated agent-harness environment.
- Breakup Pr Break up a large PR into vertical feature slices delivered incrementally via Graphite stacked PRs.