Graph schema migrations for FalkorDB.
Project description
Runic
Graph schema migrations for FalkorDB.
Runic is a lightweight, Alembic-style migration framework built specifically for FalkorDB. It brings robust revision tracking, linear graph migrations, and a powerful CLI to graph database environments, managing schema versioning through Cypher scripts and native FalkorDB syntax.
Features
- Alembic-Style Workflow — Familiar CLI verbs like
init,revision,upgrade,downgrade, andcurrent. - Graph-Native — Treats your database as a graph. Stores migration states intelligently inside dedicated nodes (e.g.,
:_FalkorMigrateVersion). - Idempotent Cypher — Encourages explicit, heavily-guarded migration steps, supporting robust backward capability even without transactional DDLs.
- Offline & Dry Run — Review generated Cypher scripts thoroughly before executing them in production.
- Rollback Snapshots — Advanced capabilities utilizing
GRAPH.COPYfor high-risk, non-reversible data migrations.
Installation
Install via pip or uv:
uv pip install runic
Or add it to an existing project:
uv add runic
[!NOTE] Runic requires Python 3.14+ and is optimized for the latest FalkorDB clients.
A Simple Example
Initialize your project and generate a new revision:
# Set up a new runic environment
runic init
# Create your first revision script
runic revision -m "create user index"
This generates a revision file in runic/versions. Open it and define your upgrades and downgrades:
"""create user index
Revision ID: 1975ea83b712
Revises: None
Create Date: 2026-05-30 14:00:00.000000
"""
from datetime import UTC, datetime
revision = "1975ea83b712"
down_revision = None
message = "create user index"
create_date = datetime.fromisoformat("2026-05-30T14:00:00+00:00")
branch_labels = []
depends_on = []
irreversible = False
snapshot = False
def upgrade(op) -> None:
op.create_range_index("User", "email")
def downgrade(op) -> None:
op.drop_range_index("User", "email")
Then apply your changes:
runic upgrade # apply all pending revisions
runic downgrade # roll back one step (default target: -1)
runic downgrade 1975e # roll back to a revision — prefix is enough
Baselining an existing graph
If you have a FalkorDB graph that was built without Runic, use baseline to bring it under management without re-running anything on the source:
# Introspect the live graph, generate a root revision, and stamp it as applied
runic baseline -m "baseline"
# Generated: runic/versions/<hex>_baseline.py
# Stamped: <hex>
# Verify the graph is now tracked
runic current
# <hex> baseline
The generated revision recreates all indexes and constraints from scratch — safe to replay on a fresh empty graph (CI, cloning, new tenants):
runic upgrade head # rebuilds the full schema on an empty graph
Re-running baseline on an already-managed graph is refused:
runic baseline -m "again"
# Error: Graph already managed by runic.migrate. Use `runic upgrade` instead.
To mark an existing graph as baselined without generating a file (useful when you manage the revision file yourself):
runic baseline --stamp-only
Baseline → autogenerate workflow
Once you have a baseline revision, use the standard autogenerate workflow to evolve the schema:
# After changing your SchemaManifest in env.py:
runic revision --autogenerate -m "add embedding index"
runic upgrade head
The baseline revision is the root of the chain (down_revision = None). Future revisions chain off it normally.
Programmatic SDK
Use runic directly in Python — no CLI, no env.py needed:
from pathlib import Path
from runic import Runic, init
from runic.migrate.adapters import create_adapter
# One-time setup: scaffold the migration directory
init(Path("runic/"))
# Connect and run
adapter = create_adapter(
"falkordb",
url="falkor://localhost:6379",
graph_name="my_graph",
)
runic = Runic(adapter, script_location=Path("runic/"))
runic.migrate.upgrade("head")
print("current:", runic.migrate.current())
print("history:", runic.migrate.get_history())
Runic is the single class you need. It handles upgrades, downgrades, stamping, history queries, and revision creation in one coherent API.
Documentation
For a full conceptual overview, advanced CLI usage, and deep dives into branching or multi-head resolution, visit the complete Runic Documentation.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file runic_py-0.2.0.tar.gz.
File metadata
- Download URL: runic_py-0.2.0.tar.gz
- Upload date:
- Size: 56.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a0c4b72a712af55bf62b0a2bd27bba94ff60e454f54bda0634869ba53b0bf21
|
|
| MD5 |
ed14252d237461c82bdb4e5d5135e185
|
|
| BLAKE2b-256 |
a47b89e97fb3b19044dfbd794aaab165a09a6c5ceefb52417c340aab2c3f600f
|
File details
Details for the file runic_py-0.2.0-py3-none-any.whl.
File metadata
- Download URL: runic_py-0.2.0-py3-none-any.whl
- Upload date:
- Size: 76.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
520d9d93d5e4c6291a9a12538ecee9c4efd4ccbe372b8ba0e67d87cb9b260e30
|
|
| MD5 |
5f80a18158fdd1c3599c728363da2978
|
|
| BLAKE2b-256 |
17a357e1df41cc8fe1e92686b5269873486703c583e07531d4152fa44ecf33ce
|