-
Notifications
You must be signed in to change notification settings - Fork 112
feat(py): A dbt adapter for Feldera (not a Feldera adapter, but a dbt adapter, that is wrapping Feldera) #5950
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mihaibudiu
merged 75 commits into
feldera:main
from
mdrakiburrahman:dev/mdrrahman/dbt-feldera
Apr 16, 2026
+8,709
−2
Merged
Changes from 2 commits
Commits
Show all changes
75 commits
Select commit
Hold shift + click to select a range
8810072
Checkpoint: Initial adapter bootstrapping and e2e tests with Docker C…
mdrakiburrahman 04438af
Fixed catalog gen and add some steps for accessing dbt UI
mdrakiburrahman 44448ab
Materialize Adventureworks as Delta Table and use DuckDB to assert ro…
mdrakiburrahman 6635196
Adding a Kafka sales table and ensuring it fires IVM
mdrakiburrahman e5af63c
Materialize the Kafka topic as Delta table and use that instead in th…
mdrakiburrahman 709b25a
Use sqlglot instead of brittle RegEx to parse Feldera SQL dialect
mdrakiburrahman 04b7b38
Break apart contributing and customer facing README
mdrakiburrahman a06c699
Update changelog
mdrakiburrahman d8afa71
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 0283a3d
Proofread
mdrakiburrahman 34d0e35
Remove test_string_size override to implement the base behavior
mdrakiburrahman 7ceaa8f
Differentiate between float vs numeric
mdrakiburrahman 3fb8dcc
Update docstring to mention Feldera transactions
mdrakiburrahman 56de322
Use NOW and add a test for it
mdrakiburrahman a870d0b
Update docstring for the expand column types
mdrakiburrahman 22fd48e
Use better type inference in seed via _infer_column_types.
mdrakiburrahman c10e3d0
Add an idempotent seed uploader and downloader
mdrakiburrahman dc4df22
Remove seeds from git in origin
mdrakiburrahman 24c7b86
Remove the models and macros as well
mdrakiburrahman ec8cf4c
Add a gitkeep to the seed folders so they are visible in git tree
mdrakiburrahman 044063c
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 3f6809b
Remove GitHub action changes - no tests in publish and remove CI test…
mdrakiburrahman 0c70a30
Use the ci-post-release.yml sed to change the version
mdrakiburrahman 2f2dcb9
Update changelog
mdrakiburrahman ec20ba2
Use Pipeline client instead of FelderaClient.get_pipeline and a few o…
mdrakiburrahman 8046bf6
compiling_states needs to be a tuple in PipelineStateManager due to P…
mdrakiburrahman a07217d
Attempt to lint for CI pipeline
mdrakiburrahman 2cafef7
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman fd88b16
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 8700b56
fix(py): fix ruff isort import ordering in dbt-feldera
mdrakiburrahman 7e05d2f
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 0280c4d
fix(py): pin ruff==0.9.10 in dbt-feldera to match CI pre-commit
mdrakiburrahman f698020
Update docstring to make it clear that this adapter uses continuous q…
mdrakiburrahman d94f0c8
Add documentation for TYPE_LABELS
mdrakiburrahman b5fb950
Update param docstring for auto_begin
mdrakiburrahman 9ecf1b2
Turn positional tuples into a ColumnDescription NamedTuple
mdrakiburrahman 8413b74
Add a docstring to connection.execute that it delegates to the cursor…
mdrakiburrahman 018cd38
Update docstring for cursor.execute
mdrakiburrahman 64afc65
Add a docstring to SqlIntent to make it clear which enum is supported…
mdrakiburrahman 5c3dd4e
Add a small docstring to DATA_INGRESS
mdrakiburrahman de5b06f
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 1859709
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 4d43b45
Clean .temp dir
mdrakiburrahman 2687e25
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 95a54f7
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman b859260
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 6f68d81
Merge branch 'feldera:main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 0a45510
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman 1d8fdcd
Move DuckDB into a container for tests so we don't need host mount
mdrakiburrahman 749e793
Add adventureworks SQL scripts to git, remove .gitkeep files
mdrakiburrahman 9aa8846
Pass 1 through PR review comments
mdrakiburrahman 37f077e
Implement Generator in sqlglot to override FLOAT and map it to REAL
mdrakiburrahman edf302b
Merge branch 'main' into dev/mdrrahman/dbt-feldera
mdrakiburrahman a64ae10
Bump version to 0.288.0
mdrakiburrahman da6aa5e
Map FLOAT to REAL in dbt macro
mdrakiburrahman ca62160
Update README
mdrakiburrahman 29c6c7c
Remove incremental materialization support, it's not required in Feldera
mdrakiburrahman da853cb
Changed Jinja macro to stored = true
mdrakiburrahman 28fa16f
Remove ambiguous "registered" reference
mdrakiburrahman ac59e4d
Make TestFelderaColumn dynamic
mdrakiburrahman b5482d3
Remove external from FelderaRelationType
mdrakiburrahman 7465e32
Remove test for no columns
mdrakiburrahman a6f2801
Factor out CATALOG_COLUMNS
mdrakiburrahman e4c50f7
Remove INTERVAL mapping in agate and run integration tests green
mdrakiburrahman dc3416c
Add a _wait_for_pipeline_idle to deterministically poll pipeline to p…
mdrakiburrahman b0150a6
Add lattice tests that are data driven
mdrakiburrahman 3f04fb6
Rename test to test_remove_nonexistent_does_not_throw
mdrakiburrahman 393d5cd
Crash test if Kafka topic isn't up and dump logs
mdrakiburrahman 2d8c874
Update docstring for update_with_views
mdrakiburrahman ab70529
Lint
mdrakiburrahman 61123e3
Dupe line
mdrakiburrahman 05e7eb5
Remove NOW and use MD5 hash
mdrakiburrahman e4e07b6
There is no relationship between connectors and views being stored
mdrakiburrahman e1ce519
Add DBT_THREADS for faster integration tests
mdrakiburrahman b0dca82
Ruff the integration test folder
mdrakiburrahman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| name: dbt-feldera Tests | ||
|
|
||
| on: | ||
| workflow_call: | ||
| workflow_dispatch: | ||
|
|
||
| defaults: | ||
| run: | ||
| shell: bash | ||
| working-directory: ./python/dbt-feldera | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| unit-tests: | ||
| name: dbt-feldera Unit Tests | ||
| runs-on: ubuntu-latest-amd64 | ||
|
mdrakiburrahman marked this conversation as resolved.
Outdated
|
||
| steps: | ||
| - uses: actions/checkout@v6 | ||
|
|
||
| - name: Install uv | ||
|
mdrakiburrahman marked this conversation as resolved.
Outdated
|
||
| uses: astral-sh/setup-uv@v2 | ||
| with: | ||
| version: "0.4.15" | ||
| enable-cache: true | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
|
mdrakiburrahman marked this conversation as resolved.
Outdated
|
||
| with: | ||
| python-version: "3.10" | ||
|
|
||
| - name: Setup venv | ||
| run: .scripts/run.sh venv | ||
|
|
||
| - name: Lint | ||
| run: .scripts/run.sh lint | ||
|
|
||
| - name: Unit tests | ||
| run: .scripts/run.sh unit-test | ||
|
|
||
| - name: Build wheel | ||
| run: .scripts/run.sh build | ||
|
|
||
| integration-tests: | ||
| name: dbt-feldera Integration Tests | ||
| runs-on: ubuntu-latest-amd64 | ||
| needs: unit-tests | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
|
|
||
| - name: Install uv | ||
|
mdrakiburrahman marked this conversation as resolved.
Outdated
|
||
| uses: astral-sh/setup-uv@v2 | ||
| with: | ||
| version: "0.4.15" | ||
| enable-cache: true | ||
|
|
||
| - name: Set up Python | ||
|
mdrakiburrahman marked this conversation as resolved.
Outdated
|
||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.10" | ||
|
|
||
| - name: Setup venv | ||
| run: .scripts/run.sh venv | ||
|
|
||
| - name: Run integration tests | ||
| run: .scripts/run.sh integration-test | ||
|
mdrakiburrahman marked this conversation as resolved.
Outdated
mdrakiburrahman marked this conversation as resolved.
Outdated
|
||
| timeout-minutes: 15 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| #!/bin/bash | ||
| # | ||
| # dbt-feldera dev/test script. Requires Python 3.10+, uv, Docker (for integration/e2e). | ||
| # | ||
| # Usage: .scripts/run.sh <target> | ||
| # | ||
| # Targets: venv | build | lint | unit-test | integration-test | e2e | all | ||
| # | ||
| # Each target is idempotent — auto-creates the venv if missing. | ||
| # Set FELDERA_SKIP_DOCKER=1 / FELDERA_URL to control Docker behavior. | ||
| # | ||
| set -euo pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" | ||
| VENV_DIR="${PROJECT_DIR}/.venv" | ||
| DOCKER_COMPOSE_FILE="${PROJECT_DIR}/integration_tests/docker-compose.yml" | ||
| DOCKER_PROJECT="feldera-dbt-test" | ||
|
|
||
| declare -A TARGETS=( | ||
| ["venv"]="Fresh venv + install deps" | ||
| ["build"]="Build wheel to dist/" | ||
| ["fix"]="ruff auto-fix + format" | ||
| ["lint"]="ruff check + format" | ||
| ["unit-test"]="pytest unit tests" | ||
| ["integration-test"]="pytest integration with Feldera in Docker" | ||
| ["e2e"]="dbt CLI end-to-end with Feldera in Docker" | ||
| ["all"]="Run all targets in sequence" | ||
| ) | ||
| TARGET_ORDER=("venv" "build" "fix" "lint" "unit-test" "integration-test" "e2e") | ||
|
|
||
| print_usage() { | ||
| echo | ||
| printf " %-20s %s\n" "TARGET" "DESCRIPTION" | ||
| printf " %-20s %s\n" "all" "${TARGETS[all]}" | ||
| for t in "${TARGET_ORDER[@]}"; do printf " %-20s %s\n" "$t" "${TARGETS[$t]}"; done | ||
| echo | ||
| echo "Usage: .scripts/run.sh <target>" | ||
| echo | ||
| } | ||
|
|
||
| TARGET="${1:-}" | ||
| if [[ -z "$TARGET" ]]; then echo "ERROR: No target provided."; print_usage; exit 1; fi | ||
| if [[ "$TARGET" != "all" && -z "${TARGETS[$TARGET]:-}" ]]; then echo "ERROR: Unknown target '$TARGET'"; print_usage; exit 1; fi | ||
|
|
||
| activate_venv() { | ||
| # shellcheck disable=SC1091 | ||
| source "${VENV_DIR}/bin/activate" | ||
| } | ||
|
|
||
| create_venv() { | ||
| rm -rf "${VENV_DIR}" | ||
| cd "${PROJECT_DIR}" | ||
| uv venv "${VENV_DIR}" | ||
| activate_venv | ||
| uv sync --all-extras | ||
| } | ||
|
|
||
| ensure_venv() { | ||
| if [[ ! -d "${VENV_DIR}" ]]; then create_venv; else activate_venv; fi | ||
| } | ||
|
|
||
| run_venv() { create_venv; } | ||
| run_build() { ensure_venv; cd "${PROJECT_DIR}"; rm -rf dist/; uv build --wheel 2>&1 | tail -5; echo " Built: $(ls dist/*.whl)"; } | ||
| run_fix() { ensure_venv; cd "${PROJECT_DIR}"; uv run ruff check --fix dbt/ tests/; uv run ruff format dbt/ tests/; } | ||
| run_lint() { ensure_venv; cd "${PROJECT_DIR}"; uv run ruff check dbt/ tests/; uv run ruff format --check dbt/ tests/; } | ||
| run_unit_test() { ensure_venv; cd "${PROJECT_DIR}"; uv run pytest tests/ -vv; } | ||
|
|
||
| start_feldera() { | ||
| docker compose -f "${DOCKER_COMPOSE_FILE}" \ | ||
| -p "${DOCKER_PROJECT}" up -d --wait --wait-timeout 300 | ||
| } | ||
|
|
||
| resolve_feldera_url() { | ||
| local base="${FELDERA_URL:-http://localhost:8080}" | ||
| if curl -sf --connect-timeout 3 "${base}/healthz" >/dev/null 2>&1; then | ||
| echo "$base" | ||
| return | ||
| fi | ||
| if [[ "$base" == *localhost* || "$base" == *127.0.0.1* ]]; then | ||
| local alt="${base//localhost/host.docker.internal}" | ||
| alt="${alt//127.0.0.1/host.docker.internal}" | ||
| if curl -sf --connect-timeout 3 "${alt}/healthz" >/dev/null 2>&1; then | ||
| echo "$alt" | ||
| return | ||
| fi | ||
| fi | ||
| echo "$base" | ||
| } | ||
|
|
||
| wait_for_feldera() { | ||
| local base="${FELDERA_URL:-http://localhost:8080}" | ||
| local alt="" | ||
| if [[ "$base" == *localhost* || "$base" == *127.0.0.1* ]]; then | ||
| alt="${base//localhost/host.docker.internal}" | ||
| alt="${alt//127.0.0.1/host.docker.internal}" | ||
| fi | ||
|
|
||
| for i in $(seq 1 60); do | ||
| if curl -sf --connect-timeout 3 "${base}/healthz" >/dev/null 2>&1; then | ||
| export FELDERA_URL="$base" | ||
| echo "Feldera is healthy at ${base}" | ||
| return 0 | ||
| fi | ||
| if [[ -n "$alt" ]] && curl -sf --connect-timeout 3 "${alt}/healthz" >/dev/null 2>&1; then | ||
| export FELDERA_URL="$alt" | ||
| echo "Feldera is healthy at ${alt} (Docker-in-Docker fallback)" | ||
| return 0 | ||
| fi | ||
| echo "Waiting for Feldera... ($i/60)" | ||
| sleep 5 | ||
| done | ||
| echo "ERROR: Feldera did not become healthy in time" | ||
| return 1 | ||
| } | ||
|
|
||
| feldera_logs() { | ||
| docker compose -f "${DOCKER_COMPOSE_FILE}" \ | ||
| -p "${DOCKER_PROJECT}" logs --tail=200 | ||
| } | ||
|
|
||
| stop_feldera() { | ||
| docker compose -f "${DOCKER_COMPOSE_FILE}" \ | ||
| -p "${DOCKER_PROJECT}" down -v --remove-orphans | ||
| } | ||
|
|
||
| run_integration_test() { | ||
| ensure_venv | ||
| cd "${PROJECT_DIR}" | ||
|
|
||
| local skip_docker="${FELDERA_SKIP_DOCKER:-}" | ||
|
|
||
| if [[ -z "$skip_docker" ]]; then | ||
| echo "Starting Feldera via Docker..." | ||
| start_feldera | ||
| wait_for_feldera | ||
| else | ||
| export FELDERA_URL="$(resolve_feldera_url)" | ||
| fi | ||
|
|
||
| echo "Using FELDERA_URL=${FELDERA_URL}" | ||
|
|
||
| local rc=0 | ||
| uv run pytest integration_tests/test_dbt_feldera.py -vv --timeout=600 -m integration || rc=$? | ||
|
|
||
| if [[ -z "$skip_docker" ]]; then | ||
| if [[ $rc -ne 0 ]]; then | ||
| echo ""; echo "── Feldera logs (last 200 lines) ──" | ||
| feldera_logs || true | ||
| fi | ||
| echo "Stopping Feldera..." | ||
| stop_feldera || true | ||
| fi | ||
|
|
||
| return $rc | ||
| } | ||
|
|
||
| run_e2e() { cd "${PROJECT_DIR}"; bash integration_tests/scripts/run-dbt-local.sh; } | ||
|
|
||
| echo "=== dbt-feldera: ${TARGET} ===" | ||
|
|
||
| case "$TARGET" in | ||
| "all") | ||
| for t in "${TARGET_ORDER[@]}"; do | ||
| echo ""; echo "── ${t} ──" | ||
| "run_${t//-/_}" | ||
| done | ||
| echo ""; echo "=== All targets completed. ===" | ||
| ;; | ||
| *) "run_${TARGET//-/_}" ;; | ||
| esac |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.