Frequently Asked Questions¶
General¶
What is Pico-SQLAlchemy?¶
Pico-SQLAlchemy provides seamless integration between Pico-IoC and SQLAlchemy, offering async support, declarative transaction management, and a clean repository pattern for data access.
What Python versions are supported?¶
Pico-SQLAlchemy requires Python 3.11 or later.
What SQLAlchemy versions are supported?¶
SQLAlchemy 2.0 or later is required for full async support.
Configuration¶
How do I configure the database connection?¶
Provide the database URL via configuration:
from pico_ioc import init, configuration, DictSource
config = configuration(DictSource({
"database": {
"url": "postgresql+asyncpg://user:pass@host/db",
"echo": False,
"pool_size": 10,
}
}))
container = init(modules=["pico_sqlalchemy", "my_app"], config=config)
What database drivers are supported?¶
Any async-compatible SQLAlchemy driver works:
- PostgreSQL:
asyncpg - SQLite:
aiosqlite - MySQL:
aiomysql
Transactions¶
What propagation modes are available?¶
| Mode | Description |
|---|---|
REQUIRED | Join existing or create new (default) |
REQUIRES_NEW | Always create a new transaction |
MANDATORY | Must have an existing transaction |
SUPPORTS | Use existing if available, otherwise none |
NOT_SUPPORTED | Suspend existing transaction |
NEVER | Must NOT have an existing transaction |
How do I use read-only transactions?¶
@transactional(read_only=True)
async def get_users(repo: UserRepository):
return await repo.find_all()
Can I set isolation levels?¶
Yes, use the isolation_level parameter:
Repositories¶
What's the difference between SQL and expression mode?¶
- SQL mode (
sql=): Write raw SQL queries - Expression mode (
expr=): Write WHERE clause expressions, table name is derived from entity
# SQL mode - full control
@query(sql="SELECT * FROM users WHERE status = :status")
async def find_by_status(self, status: str): ...
# Expression mode - cleaner for simple queries
@query(expr="status = :status")
async def find_by_status(self, status: str): ...
How do I implement pagination?¶
Use paged=True and pass a PageRequest:
from pico_sqlalchemy import PageRequest, Sort
@query(expr="active = true", paged=True)
async def find_active(self, page: PageRequest): ...
# Usage
page_req = PageRequest(page=0, size=10, sorts=[Sort("name", "ASC")])
result = await repo.find_active(page=page_req)
print(result.content) # List of items
print(result.total_elements) # Total count
Can I use dynamic sorting?¶
Dynamic sorting via PageRequest.sorts is only supported in expression mode. For SQL mode, include the ORDER BY clause in your SQL string.
Troubleshooting¶
"No active transaction" error¶
This error occurs when calling repository methods outside a transaction context. Ensure your method is decorated with @transactional or called from within a transaction.
"MANDATORY propagation requires active transaction"¶
You're using propagation="MANDATORY" but there's no existing transaction. Either call from within a transaction or change the propagation mode.
Connection pool exhausted¶
Increase pool size in the database configuration: