Supported sources
- BigQuery
- ClickHouse
- Databricks (Databricks SQL / warehouses)
- MariaDB
- MySQL
- Oracle
- PostgreSQL
- Snowflake
- Spark SQL (via Livy sessions)
- SQL Server
When to use this approach
Use these tools when you want:- A one-time migration from SQL tables into a FalkorDB property graph
- Ongoing one-way sync so FalkorDB stays updated as rows change in the source system
Prerequisites
- Rust toolchain (Cargo)
- Network access to your source system
- A reachable FalkorDB endpoint (for example
falkor://127.0.0.1:6379) - Node.js + npm (optional; only needed for control plane UI)
$BIGQUERY_ACCESS_TOKEN, $DATABRICKS_TOKEN, $MYSQL_URL, $POSTGRES_URL, $SNOWFLAKE_PASSWORD, $SPARK_AUTH_TOKEN, $SQLSERVER_CONNECTION_STRING).
Getting the tools
How the loaders work (high level)
Each loader uses JSON/YAML configuration to define:- How to read rows from the source (
table+ optional filter, or custom query) - How rows map to graph entities:
- Nodes (labels, keys, property mappings)
- Edges (relationship type, direction, endpoint matching rules)
- Per-mapping execution mode (
fullorincremental) - Optional soft-delete behavior
- State backend for incremental watermarks (typically file-backed JSON)
Common concepts
- Declarative mapping: mappings define extraction + graph writes.
- Idempotent writes: loaders use Cypher
UNWIND+MERGE. - Incremental safety: watermarks move only after successful writes.
- Restart safety: failed runs can resume from persisted state.
- Index handling: loaders apply explicit
falkordb.indexesplus inferred indexes for node keys and edge endpoint matches. - Observability: loaders expose Prometheus-style metrics with global and per-mapping counters.
Change Data Capture (CDC)
Certain loaders natively support real-time Change Data Capture beyond traditional timestamp polling:- MySQL & MariaDB: Support true CDC via binary log (Binlog) streaming, pushing precise ROW-level DML events directly to the graph.
- Oracle: Supports real-time CDC by polling Oracle LogMiner for System Change Number (SCN) updates.
- PostgreSQL: Supports native logical replication CDC (via
pgoutputplugin), seamlessly capturing inserts, updates, and hard deletes while maintaining LSN positions. - Snowflake: Supports zero-loss native CDC via Snowflake Streams, natively processing
METADATA$ACTIONevents and managing offsets using transactional boundaries without the need for manualupdated_atwatermarks.
Option A: Run a loader directly (CLI)
BigQuery → FalkorDB
ClickHouse → FalkorDB
Databricks → FalkorDB
MariaDB → FalkorDB
MySQL → FalkorDB
Oracle → FalkorDB
PostgreSQL → FalkorDB
sslmode=require (minimum) or sslmode=verify-full in POSTGRES_URL.
Snowflake → FalkorDB
Spark SQL (Livy) → FalkorDB
SQL Server → FalkorDB
Optional purge modes
Purge flags are supported by: BigQuery, ClickHouse, MariaDB, MySQL, Oracle, Snowflake, SQL Server.Schema introspection + template scaffolding
Supported by: BigQuery, ClickHouse, Databricks, MariaDB, MySQL, Oracle, PostgreSQL, Snowflake, Spark, SQL Server.- Generated templates are scaffolds and should be reviewed before production use.
- For tools that support daemon/purge modes, scaffold flags cannot be combined with daemon/purge flags in the same run.
Option B: Use the control plane (web UI + API)
The control plane discovers tools by scanning fortool.manifest.json and provides UI/API features to:
- Create and edit per-tool YAML/JSON configurations
- Preview extracted source schema
- Generate scaffold templates from source metadata
- Visualize graph topology from mappings
- Start runs (one-shot and daemon where supported) on local or Kubernetes execution backend
- Stop active runs
- Stream live logs (SSE) and view persisted logs for historical runs
- Inspect and clear per-config incremental state/watermarks
- Persist and view per-tool/per-mapping metrics snapshots in SQLite
http://localhost:3003
Configuration (environment variables):
CONTROL_PLANE_BIND(default0.0.0.0:3003)CONTROL_PLANE_REPO_ROOT(optional; repository root for manifest scan)CONTROL_PLANE_DATA_DIR(defaultcontrol-plane/data/)CONTROL_PLANE_UI_DIST(defaultcontrol-plane/ui/dist/)CONTROL_PLANE_API_KEY(optional bearer token requirement)CONTROL_PLANE_ENABLED_TOOLS(optional comma-separated allow-list, for examplepostgres,snowflake)CONTROL_PLANE_EXECUTION_BACKEND(localorkubernetes, defaultlocal)CONTROL_PLANE_K8S_NAMESPACE(namespace where Kubernetes run workloads are created)CONTROL_PLANE_K8S_RUNNER_IMAGE(multi-tool runner image reference)CONTROL_PLANE_K8S_IMAGE_PULL_POLICY(runner image pull policy)CONTROL_PLANE_K8S_SERVICE_ACCOUNT(service account used for run workloads)CONTROL_PLANE_K8S_SHARED_PVC(optional shared PVC for file-backed state)CONTROL_PLANE_K8S_ENV_SECRET/CONTROL_PLANE_K8S_ENV_CONFIGMAP(optional env sources projected to run pods)CONTROL_PLANE_K8S_KUBECTL_BIN(kubectl binary path; defaultkubectl)CONTROL_PLANE_K8S_BINARY_DIR(tool binary directory in runner image; default/opt/falkordb/bin)
GET /api/healthGET /api/tools,GET /api/tools/:tool_idPOST /api/tools/:tool_id/scaffold-templatePOST /api/tools/:tool_id/schema-graph-previewGET /api/configs,POST /api/configsGET /api/configs/:config_id,PUT /api/configs/:config_idGET /api/configs/:config_id/state,POST /api/configs/:config_id/state/clearGET /api/runs,POST /api/runsGET /api/runs/:run_id,POST /api/runs/:run_id/stopGET /api/runs/:run_id/events(SSE)GET /api/runs/:run_id/logsGET /api/metrics(optional?config_id=<uuid>)GET /api/metrics/:tool_id(optional?config_id=<uuid>)
- Runs execute either locally on the control-plane host (
local) or as Kubernetes workloads (kubernetes). - Runtime artifacts are persisted under
CONTROL_PLANE_DATA_DIR, including a SQLite DB and per-run files. - SSE auth with API key may use query-string token fallback because browser
EventSourcedoes not support custom auth headers.
Container + Kubernetes single-deployment model
The DM-SQL repository includes a single-release deployment path that pairs one control-plane instance with one multi-tool runner image:control-plane/Dockerfilebuilds the control-plane API + UI image.docker/runner.Dockerfilebuilds a runner image containing all SQL-to-FalkorDB binaries.docker/build-images.sh <version> [registry]builds both images with one version tag.deploy/helm/dm-sql-to-falkordb/provides a Helm chart for a unified deployment.
Metrics feature
All current SQL loaders expose Prometheus-style metrics with:- Global counters:
- total runs
- failed runs
- rows fetched
- rows written
- rows deleted
- Per-mapping counters:
- runs
- failed runs
- rows fetched
- rows written
- rows deleted
- BigQuery:
9995 - ClickHouse:
9991 - Databricks:
9994 - MariaDB:
9997 - MySQL:
9995 - Oracle:
9998 - PostgreSQL:
9993 - Snowflake:
9992 - Spark:
9997 - SQL Server:
9996
--metrics-port (or each loader’s corresponding *_TO_FALKORDB_METRICS_PORT environment variable) to override defaults, especially when running multiple loaders concurrently.
Operational tips
- Define node mappings before edge mappings (edges depend on nodes).
- Choose stable keys for
MERGE(primary keys are usually best). - Treat scaffold-generated mappings as a starting point; always review relationship semantics and incremental/delete logic.
- Use
RUST_LOG=info(ordebug) for richer loader diagnostics. - Keep state files and control-plane data on durable storage for long-running sync setups.
Additional resources
DM-SQL-to-FalkorDB repository: GitHub repository FalkorDB docs: Documentation homeFrequently Asked Questions
Which SQL sources are supported for migration to FalkorDB?
Which SQL sources are supported for migration to FalkorDB?
BigQuery, ClickHouse, Databricks, MariaDB, MySQL, Oracle, PostgreSQL, Snowflake, Spark SQL (via Livy), and SQL Server are all supported with dedicated Rust-based CLI loaders.
Can I run continuous sync from SQL to FalkorDB?
Can I run continuous sync from SQL to FalkorDB?
Yes. Use
--daemon --interval-secs 60 to run in daemon mode for ongoing one-way sync. The loader tracks watermarks for incremental updates so FalkorDB stays current as source rows change.How do I map SQL tables to a graph model?
How do I map SQL tables to a graph model?
Use
--introspect-schema to inspect your source schema, then --generate-template to scaffold a starter YAML mapping. Review the mapping to define nodes (from tables) and edges (from foreign keys or join tables).What is the control plane and do I need it?
What is the control plane and do I need it?
The control plane is an optional web UI + REST API for managing configurations, orchestrating runs, viewing logs, and tracking metrics. It is useful for production setups but not required for simple migrations.
Can I purge and reload data during migration?
Can I purge and reload data during migration?
Yes. Use
--purge-graph to clear the entire graph before loading, or --purge-mapping <name> to clear only specific mappings. This is useful for full refreshes of specific data segments.