Metadata-Version: 2.4
Name: muscles-sql
Version: 1.0.1
Summary: Muscles SQL data layer for repositories, migrations and AI-first workflow.
Author-email: "Denis B." <denis@butko.info>
License-Expression: MIT
Project-URL: Homepage, https://github.com/butkoden/muscles-sql
Project-URL: Repository, https://github.com/butkoden/muscles-sql
Project-URL: Documentation, https://github.com/butkoden/muscles-sql#readme
Project-URL: PyPI, https://pypi.org/project/muscles-sql/
Project-URL: Releases, https://github.com/butkoden/muscles-sql/releases
Project-URL: muscles, https://pypi.org/project/muscles/
Project-URL: muscles-documents, https://pypi.org/project/muscles-documents/
Project-URL: muscles-ai, https://pypi.org/project/muscles-ai/
Project-URL: muscles-otel, https://pypi.org/project/muscles-otel/
Project-URL: muscles-benchmarks, https://pypi.org/project/muscles-benchmarks/
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: muscles<2.0.0,>=1.0.0rc1
Requires-Dist: SQLAlchemy<3.0,>=2.0
Requires-Dist: alembic<2.0,>=1.13
Requires-Dist: click<9.0,>=8.1
Requires-Dist: pydantic<3.0,>=2.7
Provides-Extra: dev
Requires-Dist: pytest<9.0,>=8.0; extra == "dev"

# Muscles SQL

Muscles SQL is a data layer package for SQL databases:
- model-to-table mapping
- engine and session management
- repository CRUD and advanced query API (filters/operators/joins/aggregates)
- transactions and Unit of Work (nested/savepoint/retry helpers)
- migrations v2 commands (Alembic-compatible lazy-load)
- inspect/doctor support with machine-readable diagnostics

## Related Repositories

- [`muscles`](https://github.com/butkoden/muscles) - core schemas, actions, DI and canonical documentation.
- [`muscles-documents`](https://github.com/butkoden/muscles-documents) - document metadata/state can use SQL persistence in applications.
- [`muscles-ai`](https://github.com/butkoden/muscles-ai) - AI/RAG flows can use SQL-backed application state without making SQL generic storage.
- [`muscles-otel`](https://github.com/butkoden/muscles-otel) - observability hooks around SQL-backed flows.
- [`muscles-benchmarks`](https://github.com/butkoden/muscles-benchmarks) - SQL transaction and mapping regression checks.

## Quickstart

```bash
python -m venv .venv
source .venv/bin/activate
pip install muscles-sql
```

For local development with the test dependencies:

```bash
pip install -e ".[dev]"
pytest -q
muscles-sql doctor --url sqlite:///./app.db
```

## Named SQL Connections

`muscles-sql` can manage multiple SQL connections without becoming a generic
storage registry. The registry is SQL-only: it owns SQL connection configs,
lazy SQLAlchemy `EngineManager` instances, sessions, inspect and doctor reports.

```python
from muscles_sql import SqlConnectionConfig, SqlConnectionRegistry

registry = SqlConnectionRegistry(
    [
        SqlConnectionConfig(name="default", url="sqlite:///./app.db"),
        SqlConnectionConfig(name="analytics", url="sqlite:///./analytics.db", role="read"),
    ]
)

session = registry.session("analytics")
report = registry.inspect("analytics")
```

CLI diagnostics can read a JSON config:

```json
{
  "connections": {
    "default": "sqlite:///./app.db",
    "analytics": {"url": "sqlite:///./analytics.db", "role": "read"}
  }
}
```

```bash
muscles-sql inspect --config sql-connections.json --connection analytics
muscles-sql doctor --config sql-connections.json --all
```

Diagnostic output uses safe URLs and does not print passwords from DSNs.

## Advanced Query Example

```python
from sqlalchemy import func
from muscles_sql import FilterClause, JoinClause, QuerySpec, SqlRepository

spec = QuerySpec(
    filters=[FilterClause("status", "eq", "active")],
    joins=[JoinClause(table=orders, on=users.c.id == orders.c.user_id)],
    select_columns=[users.c.id, func.count(orders.c.id).label("orders_total")],
    group_by=[users.c.id],
    order_by=[users.c.id.asc()],
)
rows = SqlRepository(session, users).aggregate(spec)
```
