Metadata-Version: 2.4
Name: oceanic-mysql-orm
Version: 1.0.5
Summary: A production-grade async MySQL ORM with LoopBack-style nested relation queries, typed model instances, and zero N+1.
Project-URL: Homepage, https://gitlab.com/MaheshPulivarthi181/mysql-orm-connector
Project-URL: Documentation, https://gitlab.com/MaheshPulivarthi181/mysql-orm-connector#readme
Project-URL: Repository, https://gitlab.com/MaheshPulivarthi181/mysql-orm-connector.git
Project-URL: Issues, https://gitlab.com/MaheshPulivarthi181/mysql-orm-connector/-/issues
Project-URL: Changelog, https://gitlab.com/MaheshPulivarthi181/mysql-orm-connector/-/blob/main/CHANGELOG.md
Author: Mahesh Pulivarthi
Maintainer: Mahesh Pulivarthi
License-Expression: MIT
License-File: LICENSE
Keywords: aiomysql,async,asyncio,database,fastapi,loopback,mysql,orm,relations
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: AsyncIO
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Classifier: Topic :: Database :: Front-Ends
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Requires-Dist: aiomysql>=0.2.0
Requires-Dist: cryptography>=42.0.0
Requires-Dist: pymysql>=1.1.0
Provides-Extra: dev
Requires-Dist: build>=1.2.0; extra == 'dev'
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: twine>=5.0.0; extra == 'dev'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.110.0; extra == 'fastapi'
Requires-Dist: uvicorn[standard]>=0.29.0; extra == 'fastapi'
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
Requires-Dist: pytest>=8.0.0; extra == 'test'
Description-Content-Type: text/markdown

# 🚀 Oceanic MySQL ORM Connector

A high-performance, asynchronous MySQL ORM for Python. Built for speed, deep relational integrity, and developer transparency.

---

## 📦 Core Features
- **Async First**: Built on top of `aiomysql` for non-blocking I/O.
- **N+1 Prevention**: Intelligent batch-loading for relations (no implicit lazy-loading penalties).
- **Relational Power**: Supports One-to-One, One-to-Many, Many-to-Many (Through), and Self-referential models.
- **Additive Migrations**: Safe, non-destructive schema synchronization.
- **Debug Echo**: Real-time SQL monitoring with color-coded terminal output.

---

## 🏁 Initialization

```python
from mysql_connector import MySQLConnector

connector = MySQLConnector(
    host="127.0.0.1",
    port=3306,
    user="root",
    password="yourpassword",
    database="your_db",
    echo=True  # Enables Query Debug Mode
)

await connector.connect()
await connector.migrate() # Synchronizes schema
```

---

## 📝 Model Definition

```python
from mysql_connector import MySQLModel, Field, Relation

class User(MySQLModel):
    __table__ = "users"
    
    id    = Field(primary_key=True, auto_increment=True)
    name  = Field(nullable=False)
    email = Field(unique=True)
    
    # One-to-Many Relation
    posts = Relation("hasMany", target_model="Post", foreign_key="author_id")

class Post(MySQLModel):
    __table__ = "posts"
    
    id        = Field(primary_key=True)
    title     = Field()
    author_id = Field()
```

---

## 🔍 Query API

### find(model_class, options)
Fetches a list of instances matching the criteria.
```python
posts = await connector.find(Post, {
    "where": {"status": "published"},
    "order": ["id DESC"],
    "limit": 10,
    "include": ["author"] # Batch-loads authors
})
```

### find_one(model_class, options)
Fetches a single instance or returns `None`.

### find_by_id(model_class, pk_value, options)
Shortcut for fetching by primary key.

### create(model_instance)
Inserts a new record and triggers `before_create` hooks.

### update(model_instance)
Persists changes to an existing record.

---

## 🏗️ Relation Strategies

| Type | Direction | Batch Strategy |
| :--- | :--- | :--- |
| **belongsTo** | Child → Parent | `WHERE pk IN (...)` |
| **hasOne** | Parent → Child | `WHERE fk IN (...) LIMIT 1` |
| **hasMany** | Parent → Children | `WHERE fk IN (...)` |
| **hasManyThrough** | M2M | `Junction Query` -> `Target Query` |

---

## 🛠️ Schema Migration Policy (Safety First)

The `Migrator` follow an **Additive-Only** policy:

- **Missing Tables**: Will be created automatically.
- **Missing Columns**: Will be added (`ALTER TABLE ADD COLUMN`).
- **Extra Columns**: Will be **ignored**. The ORM will never drop a column from your database, even if it is removed from `models.py`. This prevents accidental data loss during refactoring.

**Scenario: Manual Column Removal**
If you wish to delete a column from the database, you must do so manually via SQL:
`ALTER TABLE table_name DROP COLUMN column_name;`

---

## 📡 Debugging (Echo Mode)
When `echo=True` is passed to the constructor, the ORM prints formatted SQL to the console:

```text
[ORM QUERY] SELECT * FROM users WHERE email = %s
[PARAMS]    ['alice@example.com']
```
This is essential for identifying inefficient queries during development.
