# Orthant

[![PyPI version](https://img.shields.io/pypi/v/orthant.svg?style=flat-square)](https://pypi.org/project/orthant)

**Orthant** is a migration tool for [Qdrant Vector Database](https://qdrant.tech/), inspired by the [Alembic](https://alembic.sqlalchemy.org/). It aims to bring deterministic, version-controlled schema management for your vector DB.


## Motivation

Migration management guarantees that the database state is a deterministic function of the codebase, eliminating environment drift and deployment headaches.

I have been using Alembic for as long as I can remember for my relational DB needs. However, recently I have been working increasingly around vector databases like Qdrant. While Qdrant is incredibly powerful, I found myself missing the rigorous, version-controlled workflow for managing collections, indexes, and payload schemas that I am used to. Manually applying changes across development, staging, and production environments made my life full of headaches.

That's why I built **Orthant**, a dedicated migration tool that provides the same robust, dependency-aware workflow for your Qdrant vector database.

## Installation

Orthant is available on PyPI.

- Via `uv`
    
    ```bash
    uv add orthant
    ```

- Via `pip`
    
    ```bash
    pip install orthant
    ```

## Usage

The CLI is designed to be simple and intuitive.

### 1. Configuration (`pyproject.toml`)

First, configure the path to your migrations directory in your `pyproject.toml` file. This tells Orthant where to find its files, removing the need for a command-line flag.

```toml
# pyproject.toml

[tool.orthant]
# The path where your migration environment will be initialized.
base_dir = "app/orthant"
```

### 2. Initialize the Environment

Run the `init` command. Orthant will use the path from your `pyproject.toml` to scaffold the necessary files.

```bash
orthant init
```

This creates the migration environment:
```
app/orthant/
├── versions/
├── env.py         # <-- IMPORTANT: Configure your DB connection here
├── script.py.mako
└── README.md
```

### 3. Create a New Migration

Generate a new migration script using `new`. Use the `-m` flag for a short summary, and add more `-m` flags for a longer description, just like `git commit`.

```bash
orthant new -m "Add New Collection"
```

### 4. Edit the Migration Script

Open the new file (e.g., `app/orthant/versions/20250922101337...py`) and add your logic.

```python
"""Add New Collection

Revision ID: 20250922101337
Revises:
Create Date: 2025-09-22T10:13:37.364635+00:00
"""

from qdrant_client import QdrantClient, models

# revision identifiers, used by the migration tool
revision = "20250922101337"
down_revision = "None"


def upgrade(client: QdrantClient) -> None:
    # ### commands auto-generated by Orthant - please adjust! ###
    pass
    # ### end Orthant commands ###

def downgrade(client: QdrantClient) -> None:
    # ### commands auto-generated by Orthant - please adjust! ###
    pass
    # ### end Orthant commands ###
```

### 5. Apply and Manage Migrations

```bash
# Apply all new migrations
orthant upgrade head

# Check the current state of the database
orthant current

# Revert the last applied migration
orthant downgrade

# See all commands and options
orthant --help
```

## Contributing

Contributions are welcome! Whether it's a bug report, a feature request, or a pull request, we appreciate your help. Please feel free to open an issue or submit a PR.

## Acknowledgements

-   **Alembic Team** for creating the gold standard of database migration tools, which served as the primary inspiration.
-   **Qdrant** for building an incredible open-source vector database.

## License

This project is licensed under the [BSD-2-Clause License](./LICENSE).
