Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 48 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This project packages a SQLAlchemy dialect and lightweight DBAPI 2.0 adapter tha
- Lightweight DBAPI implementation that maps Opteryx types to SQLAlchemy while surfacing DatabaseError/OperationalError semantics.
- Compatible with SQLAlchemy 2.x usage patterns, including context-managed engines and `text` queries.
- Work with pandas, dbt, or other tooling that understands SQLAlchemy engines.
- **Comprehensive debug logging** for troubleshooting connection, authentication, and query execution issues.
- Install from PyPI (`pip install opteryx-sqlalchemy`) or lock into editable mode for development.

---
Expand All @@ -25,16 +26,26 @@ Use the following SQLAlchemy URL format:
opteryx://[username:token@]host[:port]/[database][?ssl=true&timeout=60]
```

Example:
- `opteryx://user:mytoken@opteryx.app:443/default?ssl=true`
Examples:
- **Opteryx Cloud (with token)**: `opteryx://myusername:mytoken@opteryx.app:443/default?ssl=true`
- **Local Opteryx (no auth)**: `opteryx://localhost:8000/default`
- **Self-hosted (with auth)**: `opteryx://user:token@opteryx.example.com/my_database?ssl=true`

Notes:
- If `ssl=true` or port 443 is used, the driver will use HTTPS. The default port is 8000 for plain HTTP, 443 for HTTPS.
- Pass a token in place of a password for bearer token authentication.

---

## Installation
## Getting Started

### 1. Create an Opteryx Account

If you don't have an Opteryx account yet, register at: **https://opteryx.app/auth/register.html**

Once registered, you'll receive credentials (username and token) needed to authenticate.

### 2. Install the Package

Install the published package from PyPI in any environment:

Expand All @@ -59,11 +70,14 @@ Basic usage with SQLAlchemy 2.x:
```python
from sqlalchemy import create_engine, text

# Basic connection (no token)
engine = create_engine("opteryx://opteryx.app/default?ssl=true")
# Connect to Opteryx Cloud with your credentials
engine = create_engine(
"opteryx://myusername:mytoken@opteryx.app:443/default?ssl=true"
)

with engine.connect() as conn:
result = conn.execute(text("SELECT id, name FROM users LIMIT 10"))
# Run a simple query
result = conn.execute(text("SELECT * FROM public.examples.users LIMIT 10"))
for row in result:
print(row)

Expand All @@ -73,12 +87,34 @@ with engine.connect() as conn:
print(result.fetchall())
```

Token authentication example:
**Connection String Format:**
- Replace `myusername` with your Opteryx username
- Replace `mytoken` with your Opteryx authentication token
- For Opteryx Cloud, always use `opteryx.app:443` with `ssl=true`

---

## Debug Logging 🔍

The dialect includes comprehensive logging to help troubleshoot issues. Enable it with Python's standard `logging` module:

```python
engine = create_engine("opteryx://username:password@opteryx.app:443/opteryx?ssl=true")
import logging

# Enable INFO level for query timing and status
logging.basicConfig()
logging.getLogger("sqlalchemy.dialects.opteryx").setLevel(logging.INFO)

# Or enable DEBUG level for detailed request/response information
logging.getLogger("sqlalchemy.dialects.opteryx").setLevel(logging.DEBUG)
```

**What you'll see:**
- **INFO**: Authentication status, query completion times, row counts, long-running query progress
- **DEBUG**: HTTP requests/responses, query text, parameters, state transitions, execution IDs
- **WARNING**: Authentication failures, non-fatal issues
- **ERROR**: Failures with full context including HTTP status codes

---

## Using with pandas
Expand All @@ -89,9 +125,11 @@ You can use `pandas.read_sql_query` with a SQLAlchemy connection:
import pandas as pd
from sqlalchemy import create_engine

engine = create_engine("opteryx://opteryx.app/default?ssl=true")
engine = create_engine(
"opteryx://myusername:mytoken@opteryx.app:443/default?ssl=true"
)
with engine.connect() as conn:
df = pd.read_sql_query("SELECT * FROM users LIMIT 100", conn)
df = pd.read_sql_query("SELECT * FROM public.examples.users LIMIT 100", conn)
print(df.head())
```

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "opteryx-sqlalchemy"
version = "0.0.4"
version = "0.0.5"
description = "Opteryx SQLAlchemy Dialect"
requires-python = ">=3.9"
dependencies = [
Expand Down
Loading
Loading