synq-db


Namesynq-db JSON
Version 0.0.1 PyPI version JSON
download
home_pageNone
SummaryA modern, snapshot-based database migration tool for SQLAlchemy
upload_time2025-08-04 11:18:45
maintainerNone
docs_urlNone
authorSynq Contributors
requires_python>=3.9
licenseNone
keywords database migration schema snapshot sqlalchemy
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <div align="center">
  <h1 align="center">Synq</h1>
  <p align="center">
    A modern, snapshot-based database migration tool for SQLAlchemy.
  </p>

  <p align="center">
    <a href="https://pypi.org/project/synq-db/"><img alt="PyPI" src="https://img.shields.io/pypi/v/synq-db?color=blue"></a>
    <a href="https://github.com/SudoAI-DEV/Synq/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/SudoAI-DEV/Synq/actions/workflows/ci.yml/badge.svg"></a>
    <a href="https://github.com/SudoAI-DEV/Synq/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/pypi/l/synq-db"></a>
  </p>
</div>

---

**Synq** brings the fast, offline-first workflow of tools like [Drizzle ORM](https://orm.drizzle.team/) to the Python and SQLAlchemy ecosystem. Instead of connecting to a database to detect schema changes (reflection), Synq uses schema snapshots to generate new migrations. This makes the process deterministic, incredibly fast, and independent of your database's state during development.

## Core Philosophy

Why choose Synq? It's all about the workflow.

| Feature                 | **Synq (Snapshot-based)** | **Traditional (Reflection-based e.g., Alembic)** |
| ----------------------- | ----------------------------------------------------------- | ------------------------------------------------------- |
| **Generation Source** | Compares your code (`MetaData`) to a **local snapshot file**. | Compares your code (`MetaData`) to a **live database**. |
| **DB Connection?** | **Not required** to generate migrations.                    | **Required** to generate migrations.                    |
| **Speed** | Extremely fast file-based comparison.                       | Slower, involves network latency and DB queries.        |
| **Determinism** | 100% deterministic. The output only depends on your code.   | Can be influenced by the state of the reference DB.     |
| **Workflow** | Ideal for offline development and clean CI/CD pipelines.    | Tightly coupled with a development database instance.   |

## ✨ Key Features

* **Offline Migration Generation**: Create new SQL migration scripts without ever touching a database.
* **Snapshot-based Diffing**: Synq creates a `snapshot.json` file for each migration, representing the state of your schema at that point in time.
* **Pure SQL Migrations**: Generates plain, easy-to-read `.sql` files that you can inspect and even modify before applying.
* **Simple & Modern CLI**: A clean, intuitive command-line interface to manage your migration lifecycle.
* **SQLAlchemy Native**: Built on top of SQLAlchemy's powerful `MetaData` and dialect-specific DDL compilation.

## 🚀 Quick Start

#### 1. Installation

```bash
# Basic installation (includes SQLite support)
pip install synq-db

# With PostgreSQL support
pip install synq-db[postgres]

# With MySQL support  
pip install synq-db[mysql]

# With all database drivers
pip install synq-db[postgres,mysql]
```
*(Note: The package name is `synq-db` to avoid conflicts, but the command is `synq`)*

#### 2. Initialize Synq

In your project root, run:

```bash
synq init
```

This will create a `migrations` directory and a `synq.toml` configuration file.

```
.
├── my_app/
│   └── models.py
├── migrations/
│   └── meta/
└── synq.toml
```

#### 3. Define Your Models

Synq supports both SQLAlchemy 1.4+ Table definitions and SQLAlchemy 2.0+ declarative models.

**SQLAlchemy 2.0+ (Recommended):**

```python
# my_app/models.py
from datetime import datetime
from typing import Optional
from sqlalchemy import String, DateTime, ForeignKey, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship

class Base(DeclarativeBase):
    pass

metadata_obj = Base.metadata  # Reference for Synq

class User(Base):
    __tablename__ = "users"
    
    id: Mapped[int] = mapped_column(primary_key=True)
    username: Mapped[str] = mapped_column(String(50), unique=True)
    email: Mapped[str] = mapped_column(String(100), unique=True)
    created_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime, server_default=func.now()
    )
    
    posts: Mapped[list["Post"]] = relationship("Post", back_populates="author")

class Post(Base):
    __tablename__ = "posts"
    
    id: Mapped[int] = mapped_column(primary_key=True)
    title: Mapped[str] = mapped_column(String(200))
    author_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
    
    author: Mapped["User"] = relationship("User", back_populates="posts")
```

**SQLAlchemy 1.4+ (Legacy):**

```python
# my_app/models.py
from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey

metadata_obj = MetaData()

users_table = Table(
    "users", metadata_obj,
    Column("id", Integer, primary_key=True),
    Column("username", String(50), nullable=False, unique=True),
    Column("email", String(100), nullable=False, unique=True),
)

posts_table = Table(
    "posts", metadata_obj,
    Column("id", Integer, primary_key=True),
    Column("title", String(200), nullable=False),
    Column("author_id", Integer, ForeignKey("users.id")),
)
```

#### 4. Configure Synq

Edit `synq.toml` to point to your `MetaData` object and your database URI.

```toml
# synq.toml
[synq]
# Path to your SQLAlchemy MetaData instance
metadata_path = "my_app.models:metadata_obj"

# Database connection string (used only for 'migrate')
db_uri = "postgresql://user:password@localhost/mydatabase"
```

#### 5. Generate Your First Migration

Synq can automatically generate intelligent migration names, or you can provide your own:

```bash
# Auto-generate name based on detected changes
synq generate

# Provide a custom description  
synq generate "Create user and post tables"

# Use a specific name (overrides auto-generation)
synq generate --name "initial_schema"
```

Synq compares your code with an empty state and creates two new files:

```
migrations/
├── 0000_initial_migration.sql  # The generated SQL
└── meta/
    └── 0000_snapshot.json      # The schema snapshot
```

**Example generated migration names:**
- `create_users_table` - Single table creation
- `add_email_to_users` - Single column addition  
- `initial_migration` - Multiple table creation
- `update_schema` - Mixed operations across tables

#### 6. Apply the Migration

Run the migration against your database.

```bash
synq migrate -y
```

Synq connects to the database, checks which migrations haven't been applied, and runs the SQL script. Your database is now in sync with your models!

#### 7. Iterative Development

As you modify your models, Synq detects changes and generates new migrations:

```bash
# Add new models or modify existing ones in your code
# Then generate a new migration
synq generate  # Automatically detects changes

# Apply the new migration
synq migrate -y

# Check status anytime
synq status
```

## CLI Command Reference

### `synq init`
Initializes the project structure with migration directories and configuration.

```bash
synq init --metadata-path "myapp.models:metadata_obj" --db-uri "postgresql://..."
```

### `synq generate`
Generates a new migration by comparing your current schema to the latest snapshot.

```bash
# Auto-generate name based on detected operations
synq generate

# Provide custom description
synq generate "Add user authentication"

# Use specific name (overrides auto-generation)  
synq generate --name "v2_auth_system"

# Use custom config file
synq generate -c /path/to/synq.toml
```

### `synq migrate`
Applies all pending migrations to the database.

```bash
# Interactive mode (prompts for confirmation)
synq migrate

# Auto-confirm all migrations
synq migrate -y

# Dry run (show what would be applied)
synq migrate --dry-run
```

### `synq status`
Shows the current migration status and pending changes.

```bash
synq status
```

## Supported Databases

Synq supports all databases that SQLAlchemy supports:

- **SQLite** - Built-in support
- **PostgreSQL** - Install: `pip install synq-db[postgres]`
- **MySQL** - Install: `pip install synq-db[mysql]`
- **Oracle, SQL Server, etc.** - Use appropriate SQLAlchemy drivers

## Python & SQLAlchemy Support

- **Python**: 3.9, 3.10, 3.11, 3.12, 3.13
- **SQLAlchemy**: 1.4+ and 2.0+
- **Operating Systems**: Linux, macOS, Windows

## Migration Naming

Synq automatically generates intelligent migration names based on detected operations:

| Operations | Generated Name | Example |
|------------|----------------|---------|
| Single table creation | `create_{table}_table` | `create_users_table` |
| Multiple table creation | `initial_migration` | `initial_migration` |
| Single column addition | `add_{column}_to_{table}` | `add_email_to_users` |
| Multiple columns to one table | `add_columns_to_{table}` | `add_columns_to_users` |
| Mixed operations on one table | `update_{table}_schema` | `update_users_schema` |
| Mixed operations on multiple tables | `update_schema` | `update_schema` |
| Table deletion | `delete_{table}_table` | `delete_old_table` |
| Index creation | `add_{index}_to_{table}` | `add_email_index_to_users` |

You can always override auto-generated names with `--name` or by providing a description.

## 🤝 Contributing

Contributions are welcome! We are excited to see this project grow with the help of the community. Please see our `CONTRIBUTING.md` file for guidelines on how to get started.

## 📜 License

Synq is licensed under the **MIT License**. See the `LICENSE` file for more details.

## 🙏 Acknowledgments

* Heavily inspired by the fantastic workflow of **[Drizzle ORM](https://orm.drizzle.team/)**.
* Built on the powerful and robust foundation of **[SQLAlchemy](https://www.sqlalchemy.org/)**.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "synq-db",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "database, migration, schema, snapshot, sqlalchemy",
    "author": "Synq Contributors",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/46/3b/0dfe98edd780388e184ab7821b46b4e47d7178809920e0bb7ade87942662/synq_db-0.0.1.tar.gz",
    "platform": null,
    "description": "<div align=\"center\">\n  <h1 align=\"center\">Synq</h1>\n  <p align=\"center\">\n    A modern, snapshot-based database migration tool for SQLAlchemy.\n  </p>\n\n  <p align=\"center\">\n    <a href=\"https://pypi.org/project/synq-db/\"><img alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/synq-db?color=blue\"></a>\n    <a href=\"https://github.com/SudoAI-DEV/Synq/actions/workflows/ci.yml\"><img alt=\"CI\" src=\"https://github.com/SudoAI-DEV/Synq/actions/workflows/ci.yml/badge.svg\"></a>\n    <a href=\"https://github.com/SudoAI-DEV/Synq/blob/main/LICENSE\"><img alt=\"License\" src=\"https://img.shields.io/pypi/l/synq-db\"></a>\n  </p>\n</div>\n\n---\n\n**Synq** brings the fast, offline-first workflow of tools like [Drizzle ORM](https://orm.drizzle.team/) to the Python and SQLAlchemy ecosystem. Instead of connecting to a database to detect schema changes (reflection), Synq uses schema snapshots to generate new migrations. This makes the process deterministic, incredibly fast, and independent of your database's state during development.\n\n## Core Philosophy\n\nWhy choose Synq? It's all about the workflow.\n\n| Feature                 | **Synq (Snapshot-based)** | **Traditional (Reflection-based e.g., Alembic)** |\n| ----------------------- | ----------------------------------------------------------- | ------------------------------------------------------- |\n| **Generation Source** | Compares your code (`MetaData`) to a **local snapshot file**. | Compares your code (`MetaData`) to a **live database**. |\n| **DB Connection?** | **Not required** to generate migrations.                    | **Required** to generate migrations.                    |\n| **Speed** | Extremely fast file-based comparison.                       | Slower, involves network latency and DB queries.        |\n| **Determinism** | 100% deterministic. The output only depends on your code.   | Can be influenced by the state of the reference DB.     |\n| **Workflow** | Ideal for offline development and clean CI/CD pipelines.    | Tightly coupled with a development database instance.   |\n\n## \u2728 Key Features\n\n* **Offline Migration Generation**: Create new SQL migration scripts without ever touching a database.\n* **Snapshot-based Diffing**: Synq creates a `snapshot.json` file for each migration, representing the state of your schema at that point in time.\n* **Pure SQL Migrations**: Generates plain, easy-to-read `.sql` files that you can inspect and even modify before applying.\n* **Simple & Modern CLI**: A clean, intuitive command-line interface to manage your migration lifecycle.\n* **SQLAlchemy Native**: Built on top of SQLAlchemy's powerful `MetaData` and dialect-specific DDL compilation.\n\n## \ud83d\ude80 Quick Start\n\n#### 1. Installation\n\n```bash\n# Basic installation (includes SQLite support)\npip install synq-db\n\n# With PostgreSQL support\npip install synq-db[postgres]\n\n# With MySQL support  \npip install synq-db[mysql]\n\n# With all database drivers\npip install synq-db[postgres,mysql]\n```\n*(Note: The package name is `synq-db` to avoid conflicts, but the command is `synq`)*\n\n#### 2. Initialize Synq\n\nIn your project root, run:\n\n```bash\nsynq init\n```\n\nThis will create a `migrations` directory and a `synq.toml` configuration file.\n\n```\n.\n\u251c\u2500\u2500 my_app/\n\u2502   \u2514\u2500\u2500 models.py\n\u251c\u2500\u2500 migrations/\n\u2502   \u2514\u2500\u2500 meta/\n\u2514\u2500\u2500 synq.toml\n```\n\n#### 3. Define Your Models\n\nSynq supports both SQLAlchemy 1.4+ Table definitions and SQLAlchemy 2.0+ declarative models.\n\n**SQLAlchemy 2.0+ (Recommended):**\n\n```python\n# my_app/models.py\nfrom datetime import datetime\nfrom typing import Optional\nfrom sqlalchemy import String, DateTime, ForeignKey, func\nfrom sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship\n\nclass Base(DeclarativeBase):\n    pass\n\nmetadata_obj = Base.metadata  # Reference for Synq\n\nclass User(Base):\n    __tablename__ = \"users\"\n    \n    id: Mapped[int] = mapped_column(primary_key=True)\n    username: Mapped[str] = mapped_column(String(50), unique=True)\n    email: Mapped[str] = mapped_column(String(100), unique=True)\n    created_at: Mapped[Optional[datetime]] = mapped_column(\n        DateTime, server_default=func.now()\n    )\n    \n    posts: Mapped[list[\"Post\"]] = relationship(\"Post\", back_populates=\"author\")\n\nclass Post(Base):\n    __tablename__ = \"posts\"\n    \n    id: Mapped[int] = mapped_column(primary_key=True)\n    title: Mapped[str] = mapped_column(String(200))\n    author_id: Mapped[int] = mapped_column(ForeignKey(\"users.id\"))\n    \n    author: Mapped[\"User\"] = relationship(\"User\", back_populates=\"posts\")\n```\n\n**SQLAlchemy 1.4+ (Legacy):**\n\n```python\n# my_app/models.py\nfrom sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey\n\nmetadata_obj = MetaData()\n\nusers_table = Table(\n    \"users\", metadata_obj,\n    Column(\"id\", Integer, primary_key=True),\n    Column(\"username\", String(50), nullable=False, unique=True),\n    Column(\"email\", String(100), nullable=False, unique=True),\n)\n\nposts_table = Table(\n    \"posts\", metadata_obj,\n    Column(\"id\", Integer, primary_key=True),\n    Column(\"title\", String(200), nullable=False),\n    Column(\"author_id\", Integer, ForeignKey(\"users.id\")),\n)\n```\n\n#### 4. Configure Synq\n\nEdit `synq.toml` to point to your `MetaData` object and your database URI.\n\n```toml\n# synq.toml\n[synq]\n# Path to your SQLAlchemy MetaData instance\nmetadata_path = \"my_app.models:metadata_obj\"\n\n# Database connection string (used only for 'migrate')\ndb_uri = \"postgresql://user:password@localhost/mydatabase\"\n```\n\n#### 5. Generate Your First Migration\n\nSynq can automatically generate intelligent migration names, or you can provide your own:\n\n```bash\n# Auto-generate name based on detected changes\nsynq generate\n\n# Provide a custom description  \nsynq generate \"Create user and post tables\"\n\n# Use a specific name (overrides auto-generation)\nsynq generate --name \"initial_schema\"\n```\n\nSynq compares your code with an empty state and creates two new files:\n\n```\nmigrations/\n\u251c\u2500\u2500 0000_initial_migration.sql  # The generated SQL\n\u2514\u2500\u2500 meta/\n    \u2514\u2500\u2500 0000_snapshot.json      # The schema snapshot\n```\n\n**Example generated migration names:**\n- `create_users_table` - Single table creation\n- `add_email_to_users` - Single column addition  \n- `initial_migration` - Multiple table creation\n- `update_schema` - Mixed operations across tables\n\n#### 6. Apply the Migration\n\nRun the migration against your database.\n\n```bash\nsynq migrate -y\n```\n\nSynq connects to the database, checks which migrations haven't been applied, and runs the SQL script. Your database is now in sync with your models!\n\n#### 7. Iterative Development\n\nAs you modify your models, Synq detects changes and generates new migrations:\n\n```bash\n# Add new models or modify existing ones in your code\n# Then generate a new migration\nsynq generate  # Automatically detects changes\n\n# Apply the new migration\nsynq migrate -y\n\n# Check status anytime\nsynq status\n```\n\n## CLI Command Reference\n\n### `synq init`\nInitializes the project structure with migration directories and configuration.\n\n```bash\nsynq init --metadata-path \"myapp.models:metadata_obj\" --db-uri \"postgresql://...\"\n```\n\n### `synq generate`\nGenerates a new migration by comparing your current schema to the latest snapshot.\n\n```bash\n# Auto-generate name based on detected operations\nsynq generate\n\n# Provide custom description\nsynq generate \"Add user authentication\"\n\n# Use specific name (overrides auto-generation)  \nsynq generate --name \"v2_auth_system\"\n\n# Use custom config file\nsynq generate -c /path/to/synq.toml\n```\n\n### `synq migrate`\nApplies all pending migrations to the database.\n\n```bash\n# Interactive mode (prompts for confirmation)\nsynq migrate\n\n# Auto-confirm all migrations\nsynq migrate -y\n\n# Dry run (show what would be applied)\nsynq migrate --dry-run\n```\n\n### `synq status`\nShows the current migration status and pending changes.\n\n```bash\nsynq status\n```\n\n## Supported Databases\n\nSynq supports all databases that SQLAlchemy supports:\n\n- **SQLite** - Built-in support\n- **PostgreSQL** - Install: `pip install synq-db[postgres]`\n- **MySQL** - Install: `pip install synq-db[mysql]`\n- **Oracle, SQL Server, etc.** - Use appropriate SQLAlchemy drivers\n\n## Python & SQLAlchemy Support\n\n- **Python**: 3.9, 3.10, 3.11, 3.12, 3.13\n- **SQLAlchemy**: 1.4+ and 2.0+\n- **Operating Systems**: Linux, macOS, Windows\n\n## Migration Naming\n\nSynq automatically generates intelligent migration names based on detected operations:\n\n| Operations | Generated Name | Example |\n|------------|----------------|---------|\n| Single table creation | `create_{table}_table` | `create_users_table` |\n| Multiple table creation | `initial_migration` | `initial_migration` |\n| Single column addition | `add_{column}_to_{table}` | `add_email_to_users` |\n| Multiple columns to one table | `add_columns_to_{table}` | `add_columns_to_users` |\n| Mixed operations on one table | `update_{table}_schema` | `update_users_schema` |\n| Mixed operations on multiple tables | `update_schema` | `update_schema` |\n| Table deletion | `delete_{table}_table` | `delete_old_table` |\n| Index creation | `add_{index}_to_{table}` | `add_email_index_to_users` |\n\nYou can always override auto-generated names with `--name` or by providing a description.\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! We are excited to see this project grow with the help of the community. Please see our `CONTRIBUTING.md` file for guidelines on how to get started.\n\n## \ud83d\udcdc License\n\nSynq is licensed under the **MIT License**. See the `LICENSE` file for more details.\n\n## \ud83d\ude4f Acknowledgments\n\n* Heavily inspired by the fantastic workflow of **[Drizzle ORM](https://orm.drizzle.team/)**.\n* Built on the powerful and robust foundation of **[SQLAlchemy](https://www.sqlalchemy.org/)**.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A modern, snapshot-based database migration tool for SQLAlchemy",
    "version": "0.0.1",
    "project_urls": {
        "Changelog": "https://github.com/SudoAI-DEV/Synq/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/SudoAI-DEV/Synq#readme",
        "Repository": "https://github.com/SudoAI-DEV/Synq"
    },
    "split_keywords": [
        "database",
        " migration",
        " schema",
        " snapshot",
        " sqlalchemy"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b0b44c0e6a595bf452a5405e58297cdb4fc8b3f2e942643f9733fe26d8a15d46",
                "md5": "d7e32618273256a2fe2b58c1c56b7fcc",
                "sha256": "3ed4282e7fd70b3312f05494a77b7921d012fdb0c6f135f6c3aa8b90388d584d"
            },
            "downloads": -1,
            "filename": "synq_db-0.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d7e32618273256a2fe2b58c1c56b7fcc",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 28640,
            "upload_time": "2025-08-04T11:18:44",
            "upload_time_iso_8601": "2025-08-04T11:18:44.018418Z",
            "url": "https://files.pythonhosted.org/packages/b0/b4/4c0e6a595bf452a5405e58297cdb4fc8b3f2e942643f9733fe26d8a15d46/synq_db-0.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "463b0dfe98edd780388e184ab7821b46b4e47d7178809920e0bb7ade87942662",
                "md5": "8e9c53083c309fe1e77e6658af9bec9a",
                "sha256": "56d477ef88ddd869e55bbe7c0e85fbccb7dbe1dd7e1cd204e7e8e7af72dac3db"
            },
            "downloads": -1,
            "filename": "synq_db-0.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "8e9c53083c309fe1e77e6658af9bec9a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 74902,
            "upload_time": "2025-08-04T11:18:45",
            "upload_time_iso_8601": "2025-08-04T11:18:45.325062Z",
            "url": "https://files.pythonhosted.org/packages/46/3b/0dfe98edd780388e184ab7821b46b4e47d7178809920e0bb7ade87942662/synq_db-0.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-04 11:18:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "SudoAI-DEV",
    "github_project": "Synq",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "synq-db"
}
        
Elapsed time: 1.80057s