Skip to main content

Graph schema migrations for FalkorDB.

Project description

Runic logo

Runic

Graph schema migrations for FalkorDB.

Version Python License: MIT

FeaturesInstallationA Simple ExampleDocumentation


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, and current.
  • 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.COPY for 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

runic_py-0.2.0.tar.gz (56.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

runic_py-0.2.0-py3-none-any.whl (76.4 kB view details)

Uploaded Python 3

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

Hashes for runic_py-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5a0c4b72a712af55bf62b0a2bd27bba94ff60e454f54bda0634869ba53b0bf21
MD5 ed14252d237461c82bdb4e5d5135e185
BLAKE2b-256 a47b89e97fb3b19044dfbd794aaab165a09a6c5ceefb52417c340aab2c3f600f

See more details on using hashes here.

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

Hashes for runic_py-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 520d9d93d5e4c6291a9a12538ecee9c4efd4ccbe372b8ba0e67d87cb9b260e30
MD5 5f80a18158fdd1c3599c728363da2978
BLAKE2b-256 17a357e1df41cc8fe1e92686b5269873486703c583e07531d4152fa44ecf33ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page