Skip to main content

An open-source database migration engine powered by Apache Arrow

Project description

Bani

CI License Python Docs

An open-source database migration engine powered by Apache Arrow.

Bani migrates schema, data, and indexes across relational databases using Apache Arrow as a universal columnar interchange format. Define migrations declaratively with BDL, programmatically with the Python SDK, or let an AI agent drive them via the MCP server.

Features

  • 5 Database Connectors -- PostgreSQL, MySQL, MSSQL, Oracle, SQLite
  • Apache Arrow Engine -- Columnar interchange for high-throughput batch transfers
  • Declarative BDL -- Define migrations in XML or JSON, version control everything
  • Python SDK -- Fluent ProjectBuilder API for programmatic migrations
  • CLI -- 11 commands: run, validate, preview, init, schema inspect, and more
  • MCP Server -- 10 tools for AI agents (Claude, Cursor, etc.)
  • Web Dashboard -- Real-time migration monitoring with React UI
  • Cross-Platform -- macOS app, Linux packages, Windows installer, Docker

Quick Start

Install

Download the installer for your platform from the releases page (macOS .dmg, Windows .exe, Linux .deb/.rpm/AppImage), or:

# pip (Python 3.11+)
pip install bani-tools
bani ui   # opens the Web UI in your browser

# Docker
docker pull banilabs/bani:latest

Your First Migration

  1. Set up database credentials as environment variables:
export SOURCE_USER=myuser
export SOURCE_PASS=mypassword
export TARGET_USER=pguser
export TARGET_PASS=pgpassword
  1. Create a migration project:
bani init --source mysql --target postgresql --out my-migration.bdl
  1. Run the migration:
bani run my-migration.bdl

Python SDK

from bani.sdk import BaniProject, ProjectBuilder

project = (
    ProjectBuilder("my-migration")
    .source("mysql", host="localhost", port=3306, database="source_db",
            username_env="SOURCE_USER", password_env="SOURCE_PASS")
    .target("postgresql", host="localhost", port=5432, database="target_db",
            username_env="TARGET_USER", password_env="TARGET_PASS")
    .batch_size(100_000)
    .build()
)

result = BaniProject(project).run()
print(f"Migrated {result.total_rows_written} rows in {result.duration_seconds:.1f}s")

Or load from a BDL file:

from bani.sdk import Bani

result = Bani.load("my-migration.bdl").run()

MCP Server (AI Agent Integration)

Add to your Claude Desktop configuration:

{
  "mcpServers": {
    "bani": {
      "command": "bani",
      "args": ["mcp", "start"]
    }
  }
}

Then ask Claude: "Inspect the schema of my MySQL database and generate a migration to PostgreSQL."

Supported Databases

Database Versions Source Sink Driver
PostgreSQL 9.6 -- 17 Yes Yes psycopg 3.x
MySQL 5.5 -- 8.4 Yes Yes PyMySQL
SQL Server 2019 -- 2022 Yes Yes pyodbc / pymssql
Oracle 11g -- 23c Yes Yes oracledb
SQLite 3.x Yes Yes sqlite3 (stdlib)

Architecture

Bani uses Apache Arrow RecordBatch as its universal data interchange format. Source connectors read database rows into Arrow batches; sink connectors write Arrow batches to the target database. This gives N type mappers (one per connector) instead of N x N, and enables high-throughput columnar transfers with minimal Python overhead.

Source DB --> Source Connector --> Arrow RecordBatch --> Sink Connector --> Target DB

Key components:

  • Connectors -- Pluggable source/sink pairs discovered via Python entry points
  • Orchestrator -- Manages table ordering (dependency-aware), batching, parallelism, and checkpointing
  • BDL Parser -- Reads XML or JSON migration definitions into a ProjectModel
  • SDK -- ProjectBuilder for programmatic construction, SchemaInspector for introspection
  • MCP Server -- Exposes migration tools to AI agents via the Model Context Protocol

Web UI

Launch the web dashboard:

bani ui

Monitor migrations in real-time with progress tracking, table-level status, and error reporting.

Documentation

Full documentation is available at docs.bani.tools:

Development

# Clone and install
git clone https://github.com/mugumedavid/bani.git
cd bani
uv sync --all-extras --dev

# Run quality gates
ruff check && ruff format --check
mypy --strict
pytest

# Or use make
make all

See CONTRIBUTING.md for the full development guide.

License

Apache-2.0. See LICENSE for details.

Links

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

bani_tools-1.0.1-py3-none-any.whl (413.9 kB view details)

Uploaded Python 3

File details

Details for the file bani_tools-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: bani_tools-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 413.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bani_tools-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e2cbbf87305573f9ac7b63d764d4566f3701284cefb1debaf17eea27a8acef6b
MD5 3d601e5cabf7b680f7cf9c918e5bd2a4
BLAKE2b-256 117fe930e4fd6ca3f7dfab9846ef10244a7406e0d5eed04abd14e10fc6a17b22

See more details on using hashes here.

Provenance

The following attestation bundles were made for bani_tools-1.0.1-py3-none-any.whl:

Publisher: release.yml on mugumedavid/bani

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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