Metadata-Version: 2.4
Name: asyncdb-lib
Version: 0.3.1
Summary: Modern async database library with ORM, query builder, and migrations
Home-page: https://github.com/yourusername/asyncdb
Author: Your Name
Author-email: Your Name <your.email@example.com>
Maintainer-email: Your Name <your.email@example.com>
License: MIT
Project-URL: Homepage, https://github.com/yourusername/asyncdb
Project-URL: Repository, https://github.com/yourusername/asyncdb.git
Project-URL: Issues, https://github.com/yourusername/asyncdb/issues
Project-URL: Documentation, https://github.com/yourusername/asyncdb#readme
Project-URL: Changelog, https://github.com/yourusername/asyncdb/releases
Keywords: database,async,orm,postgresql,mysql,sqlite,asyncpg,aiomysql
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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 :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: asyncpg>=0.28.0
Requires-Dist: aiomysql>=0.1.1
Requires-Dist: aiosqlite>=0.19.0
Requires-Dist: click>=8.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Provides-Extra: pydantic
Requires-Dist: pydantic>=2.0.0; extra == "pydantic"
Provides-Extra: all
Requires-Dist: pydantic>=2.0.0; extra == "all"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# PyAsyncDB

Modern asynchronous database library for Python with ORM, query builder, connection pooling, migrations, and more.

[![PyPI version](https://img.shields.io/pypi/v/pyasyncdb.svg)](https://pypi.org/project/pyasyncdb/)
[![Python versions](https://img.shields.io/pypi/pyversions/pyasyncdb.svg)](https://pypi.org/project/pyasyncdb/)
[![License](https://img.shields.io/pypi/l/pyasyncdb.svg)](https://github.com/yourusername/asyncdb/blob/main/LICENSE)

## ✨ Features

- ✅ **Async/Await** - Full async support for PostgreSQL, MySQL, SQLite
- ✅ **ORM** - Django-like model definitions with relationships
- ✅ **Query Builder** - Fluent SQL builder
- ✅ **Connection Pooling** - Efficient connection management
- ✅ **Migrations** - Schema version control with CLI
- ✅ **Transactions** - ACID transactions with nested savepoints
- ✅ **Query Logging** - Slow query detection and profiling
- ✅ **Batch Operations** - Bulk insert/update/delete
- ✅ **Pydantic Integration** - Automatic validation and serialization
- ✅ **CLI Tool** - Database management from command line
- ✅ **Type Hints** - Full type annotations

## 📦 Installation

```bash
pip install pyasyncdb
```

For Pydantic support:
```bash
pip install pyasyncdb[pydantic]
```

For development:
```bash
pip install pyasyncdb[dev]
```

## 🚀 Quick Start

### Basic Usage

```python
import asyncio
from asyncdb import Database

async def main():
    db = Database("postgresql://user:pass@localhost/mydb")
    
    async with db:
        # Create table
        await db.execute("""
            CREATE TABLE IF NOT EXISTS users (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100),
                email VARCHAR(255) UNIQUE
            )
        """)
        
        # Insert
        await db.execute(
            "INSERT INTO users (name, email) VALUES ($1, $2)",
            ("John", "john@example.com")
        )
        
        # Select
        users = await db.fetch_all("SELECT * FROM users")
        print(users)

asyncio.run(main())
```

### Transactions

```python
from asyncdb import Database

db = Database("postgresql://localhost/mydb")

async with db:
    async with db.transaction():
        # All queries in transaction
        await db.execute("INSERT INTO users (name) VALUES ($1)", ("Alice",))
        await db.execute("UPDATE accounts SET balance = balance - 100 WHERE id = $1", (1,))
        await db.execute("UPDATE accounts SET balance = balance + 100 WHERE id = $2", (2,))
        # Automatically commits on success, rollbacks on error
```

### ORM with Validation

```python
from asyncdb import Database, Model, Field, PydanticModelMixin

db = Database("postgresql://localhost/mydb")

class User(Model, PydanticModelMixin):
    __tablename__ = "users"
    
    id = Field(primary_key=True, auto_increment=True)
    name = Field(type="VARCHAR", max_length=100, nullable=False)
    email = Field(type="VARCHAR", max_length=255, unique=True)
    age = Field(type="INTEGER", default=0)

async with db:
    await User.create_table(db)
    
    # Create instance
    user = User(name="Alice", email="alice@example.com", age=25)
    await user.insert(db)
    
    # Query with filters
    users = await User.objects().filter(age__gte=18).all(db)
    
    # Generate Pydantic schema
    UserSchema = User.pydantic_model()
    validated = UserSchema(name="Bob", email="bob@example.com")
```

### Query Builder

```python
from asyncdb import select, insert, update, delete

# SELECT with joins
q = (
    select("users")
    .columns("id", "name", "email")
    .left_join("orders", "users.id = orders.user_id")
    .where("age > $1", 18)
    .and_where("status = $2", "active")
    .order_by("name")
    .limit(10)
)
sql, params = q.build()

# INSERT
q = insert("users").columns("name", "email").values("John", "john@example.com")
sql, params = q.build()

# UPDATE
q = update("users").set("email", "new@example.com").where("id = $1", 1)
sql, params = q.build()

# DELETE
q = delete("users").where("id = $1", 1)
sql, params = q.build()
```

### Batch Operations

```python
from asyncdb import Database, Model, Field

db = Database("postgresql://localhost/mydb")

class User(Model):
    __tablename__ = "users"
    name = Field(type="VARCHAR", max_length=100)
    email = Field(type="VARCHAR", max_length=255)

async with db:
    # Bulk insert
    users = [
        User(name="Alice", email="alice@example.com"),
        User(name="Bob", email="bob@example.com"),
        User(name="Charlie", email="charlie@example.com"),
    ]
    await User.bulk_insert(db, users)
    
    # Bulk update
    for u in users:
        u.name = u.name.upper()
    await User.bulk_update(db, users)
    
    # Bulk delete
    await User.bulk_delete(db, [1, 2, 3])
```

### Query Logging & Debugging

```python
from asyncdb import Database
import logging

logging.basicConfig(level=logging.INFO)

# Enable query logging
db = Database("postgresql://localhost/mydb", echo=True, slow_query_threshold=0.5)

async with db:
    await db.execute("SELECT * FROM users")
    await db.execute("SELECT * FROM orders WHERE amount > 1000")  # Slow query
    
    # Get slow queries
    slow = db.get_slow_queries()
    print(f"Slow queries: {len(slow)}")
    
    # Get all query log
    log = db.get_query_log()
    for entry in log:
        print(f"{entry['duration']:.3f}s - {entry['query']}")
```

## 🛠 CLI Commands

```bash
# Set database URL
export DATABASE_URL="postgresql://user:pass@localhost/mydb"

# Run migrations
pyasyncdb migrate-up

# Rollback migrations
pyasyncdb migrate-down --steps 2

# Check migration status
pyasyncdb migrate-status

# Create new migration
pyasyncdb migrate-create add_users_table

# Interactive shell
pyasyncdb shell

# Inspect database
pyasyncdb inspect
```

## 📊 Database URLs

```
postgresql://user:pass@host:5432/dbname
mysql://user:pass@host:3306/dbname
sqlite:///path/to/database.db
```

## 📖 API Reference

### Database

| Method | Description |
|--------|-------------|
| `connect()` | Establish connection |
| `disconnect()` | Close connection |
| `execute(query, params)` | Execute query |
| `fetch_one(query, params)` | Fetch single row |
| `fetch_all(query, params)` | Fetch all rows |
| `fetch_val(query, params)` | Fetch single value |
| `fetch_col(query, params)` | Fetch single column |
| `transaction()` | Transaction context |
| `get_query_log()` | Get query history |
| `get_slow_queries()` | Get slow queries |

### Model

| Method | Description |
|--------|-------------|
| `create_table(db)` | Create table |
| `drop_table(db)` | Drop table |
| `insert(db)` | Insert instance |
| `update(db)` | Update instance |
| `delete(db)` | Delete instance |
| `save(db)` | Insert or update |
| `bulk_insert(db, instances)` | Bulk insert |
| `bulk_update(db, instances)` | Bulk update |
| `bulk_delete(db, ids)` | Bulk delete |
| `objects()` | Get queryset |
| `pydantic_model()` | Generate Pydantic schema |

### QuerySet

| Method | Description |
|--------|-------------|
| `filter(**kwargs)` | Add WHERE filters |
| `exclude(**kwargs)` | Add NOT filters |
| `order_by(*fields)` | Add ORDER BY |
| `limit(n)` | Add LIMIT |
| `offset(n)` | Add OFFSET |
| `all(db)` | Fetch all |
| `first(db)` | Fetch first |
| `count(db)` | Count records |
| `exists(db)` | Check existence |

## 📝 License

MIT License - see [LICENSE](LICENSE) for details.

## 🤝 Contributing

Contributions welcome! Please read our contributing guidelines first.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📧 Support

- Documentation: https://github.com/yourusername/asyncdb#readme
- Issues: https://github.com/yourusername/asyncdb/issues
- PyPI: https://pypi.org/project/pyasyncdb/
