{"id":16454727,"url":"https://github.com/bolajiolajide/kat","last_synced_at":"2026-02-19T03:05:15.773Z","repository":{"id":88782074,"uuid":"604179914","full_name":"BolajiOlajide/kat","owner":"BolajiOlajide","description":"Database migration tool based on Sourcegraph's sg CLI and golang-migrate ","archived":false,"fork":false,"pushed_at":"2025-04-02T21:56:22.000Z","size":420,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T22:30:28.918Z","etag":null,"topics":["cli","database","migration","postgresql"],"latest_commit_sha":null,"homepage":"https://kat.bolaji.de","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BolajiOlajide.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-20T14:00:28.000Z","updated_at":"2025-04-02T21:56:25.000Z","dependencies_parsed_at":"2024-12-17T20:29:15.587Z","dependency_job_id":"e1d03cf3-f4f0-42b7-bc2d-916ad6d8c7ce","html_url":"https://github.com/BolajiOlajide/kat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BolajiOlajide%2Fkat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BolajiOlajide%2Fkat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BolajiOlajide%2Fkat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BolajiOlajide%2Fkat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BolajiOlajide","download_url":"https://codeload.github.com/BolajiOlajide/kat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247217221,"owners_count":20903009,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","database","migration","postgresql"],"created_at":"2024-10-11T10:19:50.361Z","updated_at":"2026-02-19T03:05:15.768Z","avatar_url":"https://github.com/BolajiOlajide.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kat\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/BolajiOlajide/kat/blob/main/LICENSE)\n[![Go Report Card](https://goreportcard.com/badge/github.com/BolajiOlajide/kat)](https://goreportcard.com/report/github.com/BolajiOlajide/kat)\n[![Go Reference](https://pkg.go.dev/badge/github.com/BolajiOlajide/kat.svg)](https://pkg.go.dev/github.com/BolajiOlajide/kat)\n[![CI](https://github.com/BolajiOlajide/kat/actions/workflows/ci.yml/badge.svg)](https://github.com/BolajiOlajide/kat/actions/workflows/ci.yml)\n[![Release](https://github.com/BolajiOlajide/kat/actions/workflows/release.yml/badge.svg)](https://github.com/BolajiOlajide/kat/actions/workflows/release.yml)\n[![Docs](https://img.shields.io/badge/docs-kat.bolaji.de-blue)](https://kat.bolaji.de/)\n\n\u003cdetails\u003e\n\u003csummary\u003e📑 Table of Contents\u003c/summary\u003e\n\n- [Why Graph-Based Migrations?](#why-graph-based-migrations)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Comparison with Other Tools](#comparison-with-other-tools)\n- [Architecture Overview](#architecture-overview)\n- [Go Library Usage](#go-library-usage)\n- [Best Practices](#best-practices)\n- [Limitations](#limitations)\n- [Quick Reference](#quick-reference)\n- [Documentation](#documentation)\n\n\u003c/details\u003e\n\nKat is (probably?) the first open-source PostgreSQL migration tool that treats your schema as a Directed Acyclic Graph, not a linear log. It enables topological sort migrations with explicit dependencies, parallel development workflows, and deterministic ordering.\n\n![Kat Banner](doc/assets/images/layout/logo.png)\n\n## Features\n\n- **Simple SQL Migrations**: Write raw SQL for both up and down migrations\n- **Graph-Based Migration System**: Manages parent-child relationships between migrations using a directed acyclic graph\n- **Explicit Dependencies**: Migrations can declare parent dependencies to ensure proper execution order\n- **Transaction Support**: Migrations run within transactions for safety\n- **Migration Tracking**: Applied migrations are recorded in a database table\n- **Dry Run Mode**: Validate migrations without applying them\n- **Environment Variable Support**: Secure your database credentials\n- **Rollback Support**: Easily revert migrations\n- **Idempotent Migrations**: Well-written migrations can be run multiple times safely\n- **Custom Logger Support**: Configure custom logging for migrations\n- **Go Library**: Use Kat programmatically in your Go applications\n\n## Why Graph-Based Migrations?\n\nTraditional migration tools force you into a linear sequence where every developer must coordinate their schema changes. Kat's graph-based approach solves this by allowing migrations to declare explicit parent dependencies, creating a Directed Acyclic Graph (DAG) that determines execution order.\n\n**Benefits of the DAG approach:**\n- **Parallel Development**: Multiple developers can create feature migrations simultaneously without conflicts\n- **Deterministic Ordering**: Kat computes the optimal execution order based on dependencies, not timestamps\n- **Safe Branching**: Feature branches can include their own migrations that merge cleanly\n- **Complex Dependencies**: A migration can depend on multiple parents, enabling sophisticated schema evolution\n\n```text\nLinear (traditional):     Graph-based (Kat):\n\n001_users                 001_users ──┬─→ 003_posts\n002_posts                             │\n003_add_email             002_add_email ──┘\n\nOrder: 1→2→3              Order: 1→2→3 OR 1→3→2\n(rigid)                   (flexible, dependency-aware)\n```\n\nThis means you can create migrations for different features in parallel, and Kat will figure out the correct order when you run `kat up`.\n\n## Installation\n\n### Quick Install (macOS \u0026 Linux)\n\n```bash\ncurl -sSL https://kat.bolaji.de/install | sudo bash\n```\n\n### From Pre-compiled Binaries\n\nDownload the appropriate binary for your operating system from the [releases page](https://github.com/BolajiOlajide/kat/releases).\n\n### From Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/BolajiOlajide/kat.git\ncd kat\n\n# Install\nmake install\n```\n\nFor more installation options, see the [installation documentation](https://kat.bolaji.de/install/).\n\n## Quick Start\n\nHere's a realistic example showing how Kat's graph-based system handles parallel development:\n\n```bash\n# Initialize a new Kat project\nkat init\n\n# Create foundation migration\nkat add create_users_table\n\n# Developer A: Add email feature (Kat determines create_users_table as parent)\nkat add add_email_column\n\n# Developer B: Add posts feature (creates parallel branch from users table)  \nkat add create_posts_table\n\n# Developer C: Add full-text search (Kat resolves dependencies automatically)\nkat add add_full_text_search\n\n# Visualize the dependency graph\nkat export --file graph.dot\ndot -Tpng graph.dot -o migrations.png  # Requires Graphviz\n\n# Apply all migrations - Kat determines the correct order automatically\nkat up\n\n# Test database connection\nkat ping\n\n# Roll back specific number of migrations\nkat down --count 2\n```\n\n### Example Migration Structure\n\nEach migration is a directory containing SQL files and metadata:\n\n```\nmigrations/\n├── 1679012345_create_users_table/\n│   ├── up.sql\n│   ├── down.sql\n│   └── metadata.yaml\n├── 1679012398_add_email_column/\n│   ├── up.sql\n│   ├── down.sql\n│   └── metadata.yaml      # parents: [1679012345]\n└── 1679012401_create_posts_table/\n    ├── up.sql\n    ├── down.sql\n    └── metadata.yaml          # parents: [1679012345]\n```\n\n**metadata.yaml example:**\n```yaml\nid: 1679012398\nname: add_email_column\ndescription: Add email column to users table\nparents:\n  - 1679012345  # create_users_table\n```\n\n## Usage\n\n### Configuration\n\nKat uses a YAML configuration file (`kat.conf.yaml`) to specify:\n- Database connection details\n- Migration tracking table name\n- Migration directory\n\nExample configuration:\n\n```yaml\nmigration:\n  tablename: migrations\n  directory: migrations\ndatabase:\n  url: postgres://username:password@localhost:5432/mydatabase\n  # Alternatively, use environment variables for secure credential management:\n  # url: ${DATABASE_URL}\n  # Or specify individual connection parameters:\n  # host: ${DB_HOST}\n  # port: ${DB_PORT}\n  # user: ${DB_USER}\n  # password: ${DB_PASSWORD}\n  # dbname: ${DB_NAME}\n```\n\n### Commands\n\n| Command                        | Description |\n|--------------------------------|-------------|\n| `kat init`                     | Initialize a new Kat project with configuration |\n| `kat add NAME`                 | Create a new migration with the given name |\n| `kat up [--count / -n]`        | Apply all pending migrations |\n| `kat down [--count / -n]`      | Roll back the most recent migration(s) |\n| `kat ping`                     | Test database connectivity |\n| `kat export [--file FILENAME]` | Export the migration graph in DOT format for visualization |\n| `kat version`                  | Display the current version |\n| `kat --help`                   | Show help for all commands |\n\nFor detailed usage instructions, see the [documentation](https://kat.bolaji.de/).\n\n## Comparison with Other Tools\n\n| Feature | Kat | Flyway | Goose | Atlas |\n|---------|-----|---------|-------|-------|\n| Graph-based dependencies | ✅ | ❌ | ❌ | ⚠️ |\n| Parallel development friendly | ✅ | ❌ | ❌ | ⚠️ |\n| Raw SQL migrations | ✅ | ✅ | ✅ | ⚠️ |\n| Go library + CLI | ✅ | ❌ | ✅ | ✅ |\n| Transaction per migration | ✅ | ✅ | ✅ | ✅ |\n| Rollback support | ✅ | ✅ | ✅ | ✅ |\n| Migration visualization | ✅ | ❌ | ❌ | ✅ |\n\n## Architecture Overview\n\n```\n┌─────────────┐    ┌──────────────┐    ┌─────────────┐    ┌──────────────┐\n│ CLI Command │ -\u003e │   Migration  │ -\u003e │    Graph    │ -\u003e │   Runner     │\n│   (cmd/)    │    │ (discovery)  │    │  (DAG ops)  │    │ (execution)  │\n└─────────────┘    └──────────────┘    └─────────────┘    └──────────────┘\n                           │                    │                 │\n                           v                    v                 v\n                   ┌──────────────┐    ┌─────────────┐    ┌──────────────┐\n                   │  File System │    │ Topological │    │   Database   │\n                   │   Scanner    │    │    Sort     │    │  Operations  │\n                   └──────────────┘    └─────────────┘    └──────────────┘\n```\n\n**Flow**: Discovery → Graph Construction → Topological Ordering → Transactional Execution\n\n## Go Library Usage\n\nKat can also be used as a Go library in your applications:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"embed\"\n    \"log\"\n    \"time\"\n\n    \"github.com/BolajiOlajide/kat\"\n)\n\n//go:embed migrations\nvar migrationsFS embed.FS\n\nfunc main() {\n    // Basic usage with embedded migrations\n    m, err := kat.New(\"postgres://user:pass@localhost:5432/db\", migrationsFS, \"migrations\")\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Apply all pending migrations with cancellation\n    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n    defer cancel()\n\n    err = m.Up(ctx, 0) // 0 = apply all pending\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Roll back the most recent migration\n    err = m.Down(context.Background(), 1)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Advanced usage with custom logger and existing DB connection\n    connStr := \"postgres://user:pass@localhost:5432/db\"\n    db, _ := sql.Open(\"postgres\", connStr)\n    m, err = kat.New(\"\", migrationsFS, \"schema_migrations\",\n        kat.WithLogger(customLogger),\n        kat.WithSqlDB(db), // Reuse existing connection\n    )\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\nFor more details on custom logging, see the [logger documentation](https://kat.bolaji.de/logger/).\n\n## Best Practices\n\n### Writing Idempotent Migrations\n```sql\n-- up.sql\nCREATE TABLE IF NOT EXISTS users (\n    id SERIAL PRIMARY KEY,\n    email VARCHAR(255) UNIQUE\n);\n\n-- down.sql\nDROP TABLE IF EXISTS users;\n```\n\n### Branch Workflow\n1. Create feature branch: `git checkout -b feature/user-profiles`\n2. Add dependent migrations: `kat add add_profile_table` (Kat determines dependencies)\n3. Test locally: `kat up --dry-run`\n4. Merge: Kat automatically handles dependency ordering\n\n### CI/CD Integration\n```yaml\n# .github/workflows/migrations.yml\n- name: Validate migrations\n  run: |\n    kat ping\n    kat up --dry-run\n```\n\n**Compatibility**: Tested with Go 1.20+ (tested on 1.23), PostgreSQL 12-16. Supported OS: Linux, macOS, Windows (amd64/arm64)\n\n## Quick Reference\n\n| Command | Purpose | Common Flags |\n|---------|---------|--------------|\n| `kat add NAME` | Create migration (Kat determines dependencies) | `--config, -c` |\n| `kat up --count 3` | Apply next 3 migrations | `--dry-run, --verbose` |\n| `kat down --count 2` | Roll back 2 migrations | `--force` |\n| `kat export --file graph.dot` | Export dependency graph | `--format json` |\n| `kat ping` | Test database connectivity | |\n\n➡️ *Need help?* Visit [GitHub Discussions](https://github.com/BolajiOlajide/kat/discussions) for questions and [GitHub Issues](https://github.com/BolajiOlajide/kat/issues) for bug reports.\n\n## Documentation\n\nVisit the [Kat documentation site](https://kat.bolaji.de/) for detailed guides:\n\n- [Installation](https://kat.bolaji.de/installation/)\n- [Initialization](https://kat.bolaji.de/init/)\n- [Configuration](https://kat.bolaji.de/config/)\n- [Database Connectivity](https://kat.bolaji.de/ping/)\n- [Working with Migrations](https://kat.bolaji.de/migration/)\n- [Custom Logger Configuration](https://kat.bolaji.de/logger/)\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\nKat is inspired by [Sourcegraph's internal CLI tooling](https://github.com/sourcegraph/sourcegraph-public-snapshot/tree/main/dev/sg).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbolajiolajide%2Fkat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbolajiolajide%2Fkat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbolajiolajide%2Fkat/lists"}