{"id":34586059,"url":"https://github.com/dev-five-git/vespertide","last_synced_at":"2026-04-02T18:55:53.064Z","repository":{"id":327994626,"uuid":"1112970712","full_name":"dev-five-git/vespertide","owner":"dev-five-git","description":"An open-source library for easily defining database schemas in JSON/YAML and automatically generating migration files","archived":false,"fork":false,"pushed_at":"2026-02-20T19:31:16.000Z","size":1706,"stargazers_count":18,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-21T01:10:34.430Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/dev-five-git.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":"dev-five-git","patreon":"JeongMinOh"}},"created_at":"2025-12-09T10:51:17.000Z","updated_at":"2026-02-20T19:28:16.000Z","dependencies_parsed_at":"2026-01-19T10:02:32.204Z","dependency_job_id":null,"html_url":"https://github.com/dev-five-git/vespertide","commit_stats":null,"previous_names":["dev-five-git/vespertide"],"tags_count":435,"template":false,"template_full_name":null,"purl":"pkg:github/dev-five-git/vespertide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-five-git%2Fvespertide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-five-git%2Fvespertide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-five-git%2Fvespertide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-five-git%2Fvespertide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dev-five-git","download_url":"https://codeload.github.com/dev-five-git/vespertide/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-five-git%2Fvespertide/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29746499,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-12-24T10:31:31.162Z","updated_at":"2026-02-23T15:00:59.956Z","avatar_url":"https://github.com/dev-five-git.png","language":"Rust","funding_links":["https://github.com/sponsors/dev-five-git","https://patreon.com/JeongMinOh"],"categories":[],"sub_categories":[],"readme":"# Vespertide\n\nDeclarative database schema management. Define your schemas in JSON, and Vespertide automatically generates migration plans and SQL from model diffs.\n\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![GitHub Actions](https://img.shields.io/github/actions/workflow/status/dev-five-git/vespertide/CI.yml?branch=main\u0026label=CI)](https://github.com/dev-five-git/vespertide/actions)\n[![Codecov](https://img.shields.io/codecov/c/github/dev-five-git/vespertide)](https://codecov.io/gh/dev-five-git/vespertide)\n[![Crates.io](https://img.shields.io/crates/v/vespertide-cli.svg)](https://crates.io/crates/vespertide-cli)\n\n## Features\n\n- **Declarative Schema**: Define your desired database state in JSON files\n- **Automatic Diffing**: Vespertide compares your models against applied migrations to compute changes\n- **Migration Planning**: Generates typed migration actions (not raw SQL) for safety and portability\n- **Multi-Database Support**: PostgreSQL, MySQL, SQLite\n- **Enum Types**: Native string enums and integer enums (no migration needed for new values)\n- **Zero-Runtime Migrations**: Compile-time macro generates database-specific SQL\n- **JSON Schema Validation**: Ships with JSON Schemas for IDE autocompletion and validation\n- **ORM Export**: Export schemas to SeaORM, SQLAlchemy, SQLModel\n\n## Installation\n\n```bash\ncargo install vespertide-cli\n```\n\n## Quick Start\n\n```bash\n# Initialize a new project\nvespertide init\n\n# Create a model template\nvespertide new user\n\n# Edit models/user.json, then check changes\nvespertide diff\n\n# Preview the SQL\nvespertide sql\n\n# Generate a migration file\nvespertide revision -m \"create user table\"\n```\n\n## CLI Commands\n\n| Command | Description |\n|---------|-------------|\n| `vespertide init` | Create `vespertide.json` configuration file |\n| `vespertide new \u003cname\u003e` | Create a new model template with JSON Schema reference |\n| `vespertide diff` | Show pending changes between migrations and current models |\n| `vespertide sql` | Print SQL statements for the next migration |\n| `vespertide sql --backend mysql` | SQL for specific backend (postgres/mysql/sqlite) |\n| `vespertide revision -m \"\u003cmsg\u003e\"` | Persist pending changes as a migration file |\n| `vespertide status` | Show configuration and sync status overview |\n| `vespertide log` | List applied migrations with generated SQL |\n| `vespertide export --orm seaorm` | Export models to ORM code |\n\n## Model Definition\n\nModels are JSON files in the `models/` directory. Always include `$schema` for IDE validation:\n\n```json\n{\n  \"$schema\": \"https://raw.githubusercontent.com/dev-five-git/vespertide/refs/heads/main/schemas/model.schema.json\",\n  \"name\": \"user\",\n  \"columns\": [\n    { \"name\": \"id\", \"type\": \"integer\", \"nullable\": false, \"primary_key\": true },\n    { \"name\": \"email\", \"type\": \"text\", \"nullable\": false, \"unique\": true, \"index\": true },\n    { \"name\": \"name\", \"type\": { \"kind\": \"varchar\", \"length\": 100 }, \"nullable\": false },\n    { \n      \"name\": \"status\", \n      \"type\": { \"kind\": \"enum\", \"name\": \"user_status\", \"values\": [\"active\", \"inactive\", \"banned\"] },\n      \"nullable\": false,\n      \"default\": \"'active'\"\n    },\n    { \"name\": \"created_at\", \"type\": \"timestamptz\", \"nullable\": false, \"default\": \"NOW()\" }\n  ]\n}\n```\n\n### Column Types\n\n**Simple Types:**\n\n| Type | SQL Type | Type | SQL Type |\n|------|----------|------|----------|\n| `\"integer\"` | INTEGER | `\"text\"` | TEXT |\n| `\"big_int\"` | BIGINT | `\"boolean\"` | BOOLEAN |\n| `\"small_int\"` | SMALLINT | `\"uuid\"` | UUID |\n| `\"real\"` | REAL | `\"json\"` | JSON |\n| `\"double_precision\"` | DOUBLE PRECISION | `\"jsonb\"` | JSONB |\n| `\"date\"` | DATE | `\"bytea\"` | BYTEA |\n| `\"time\"` | TIME | `\"inet\"` | INET |\n| `\"timestamp\"` | TIMESTAMP | `\"cidr\"` | CIDR |\n| `\"timestamptz\"` | TIMESTAMPTZ | `\"macaddr\"` | MACADDR |\n| `\"interval\"` | INTERVAL | `\"xml\"` | XML |\n\n**Complex Types:**\n\n```json\n{ \"kind\": \"varchar\", \"length\": 255 }\n{ \"kind\": \"char\", \"length\": 2 }\n{ \"kind\": \"numeric\", \"precision\": 10, \"scale\": 2 }\n{ \"kind\": \"enum\", \"name\": \"status\", \"values\": [\"active\", \"inactive\"] }\n{ \"kind\": \"custom\", \"custom_type\": \"TSVECTOR\" }\n```\n\n### Enum Types (Recommended)\n\nUse enums instead of text columns for status fields and categories:\n\n**String Enum** (PostgreSQL native enum):\n```json\n{\n  \"name\": \"status\",\n  \"type\": { \"kind\": \"enum\", \"name\": \"order_status\", \"values\": [\"pending\", \"shipped\", \"delivered\"] },\n  \"nullable\": false,\n  \"default\": \"'pending'\"\n}\n```\n\n**Integer Enum** (stored as INTEGER, no DB migration needed for new values):\n```json\n{\n  \"name\": \"priority\",\n  \"type\": {\n    \"kind\": \"enum\",\n    \"name\": \"priority_level\",\n    \"values\": [\n      { \"name\": \"low\", \"value\": 0 },\n      { \"name\": \"medium\", \"value\": 10 },\n      { \"name\": \"high\", \"value\": 20 }\n    ]\n  },\n  \"nullable\": false,\n  \"default\": 10\n}\n```\n\n### Inline Constraints (Preferred)\n\nDefine constraints directly on columns instead of using table-level `constraints`:\n\n```json\n{\n  \"name\": \"author_id\",\n  \"type\": \"integer\",\n  \"nullable\": false,\n  \"foreign_key\": {\n    \"ref_table\": \"user\",\n    \"ref_columns\": [\"id\"],\n    \"on_delete\": \"cascade\"\n  },\n  \"index\": true\n}\n```\n\n**Reference Actions** (snake_case): `\"cascade\"`, `\"restrict\"`, `\"set_null\"`, `\"set_default\"`, `\"no_action\"`\n\n**Composite Primary Key** (inline):\n```json\n{ \"name\": \"user_id\", \"type\": \"integer\", \"nullable\": false, \"primary_key\": true },\n{ \"name\": \"role_id\", \"type\": \"integer\", \"nullable\": false, \"primary_key\": true }\n```\n\n**Table-level constraints** are only needed for CHECK expressions:\n```json\n\"constraints\": [\n  { \"type\": \"check\", \"name\": \"check_positive\", \"expr\": \"amount \u003e 0\" }\n]\n```\n\nSee [SKILL.md](SKILL.md) for complete documentation.\n\n## Migration Files\n\n\u003e **Important**: Migration files are auto-generated. Never create or edit them manually.\n\n```bash\n# Always use the CLI to create migrations\nvespertide revision -m \"add status column\"\n```\n\nThe only exception is adding `fill_with` values when prompted (for NOT NULL columns without defaults).\n\n## Supported Databases\n\n| Database | Identifier Quoting | Notes |\n|----------|-------------------|-------|\n| PostgreSQL | `\"identifier\"` | Full feature support |\n| MySQL | `` `identifier` `` | Full feature support |\n| SQLite | `\"identifier\"` | Full feature support |\n\n## ORM Export\n\n```bash\nvespertide export --orm seaorm      # Rust - SeaORM entities\nvespertide export --orm sqlalchemy  # Python - SQLAlchemy models\nvespertide export --orm sqlmodel    # Python - SQLModel (FastAPI)\n```\n\n## Runtime Migrations (Macro)\n\nUse the `vespertide_migration!` macro to run migrations at application startup:\n\n```toml\n[dependencies]\nvespertide = \"0.1\"\nsea-orm = { version = \"2.0.0-rc\", features = [\"sqlx-postgres\", \"runtime-tokio-native-tls\", \"macros\"] }\n```\n\n```rust\nuse sea_orm::Database;\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    let db = Database::connect(\"postgres://user:pass@localhost/mydb\").await?;\n    vespertide::vespertide_migration!(db).await?;\n    Ok(())\n}\n```\n\nThe macro generates database-specific SQL at compile time for zero-runtime overhead.\n\n## Architecture\n\n```\nvespertide/\n├── vespertide-core      # Data structures (TableDef, ColumnDef, MigrationAction)\n├── vespertide-planner   # Schema diffing and migration planning\n├── vespertide-query     # SQL generation (PostgreSQL, MySQL, SQLite)\n├── vespertide-cli       # Command-line interface\n├── vespertide-exporter  # ORM code generation\n├── vespertide-macro     # Compile-time migration macro\n└── vespertide-config    # Configuration management\n```\n\n### How It Works\n\n1. **Define Models**: Write table definitions in JSON files with `$schema` for validation\n2. **Replay Migrations**: Applied migrations are replayed to reconstruct the baseline schema\n3. **Diff Schemas**: Current models are compared against the baseline\n4. **Generate Plan**: Changes are converted into typed `MigrationAction` enums\n5. **Emit SQL**: Migration actions are translated to database-specific SQL\n\n## Configuration\n\n`vespertide.json`:\n\n```json\n{\n  \"modelsDir\": \"models\",\n  \"migrationsDir\": \"migrations\",\n  \"tableNamingCase\": \"snake\",\n  \"columnNamingCase\": \"snake\",\n  \"modelFormat\": \"json\"\n}\n```\n\n## Development\n\n```bash\ncargo build                              # Build\ncargo test                               # Test\ncargo clippy --all-targets --all-features # Lint\ncargo fmt                                # Format\ncargo run -p vespertide-schema-gen -- --out schemas  # Regenerate JSON Schemas\n```\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-five-git%2Fvespertide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdev-five-git%2Fvespertide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-five-git%2Fvespertide/lists"}