-
-
Notifications
You must be signed in to change notification settings - Fork 55
Description
Issue Description
Currently, advanced_alchemy.extensions.litestar
provides submodules like repository
, base
, service
, etc. as attributes of the main module, but they cannot be imported directly as submodules.
Current Behavior
❌ This doesn't work:
from advanced_alchemy.extensions.litestar.repository import SQLAlchemyAsyncRepository
✅ This works but is less IDE-friendly:
from advanced_alchemy.extensions.litestar import repository
SQLAlchemyAsyncRepository = repository.SQLAlchemyAsyncRepository
Expected Behavior
It would be great if users could import directly from submodules for better IDE support and more intuitive import patterns:
from advanced_alchemy.extensions.litestar.repository import SQLAlchemyAsyncRepository, SQLAlchemySyncRepository
from advanced_alchemy.extensions.litestar.base import BigIntAuditBase, UUIDAuditBase
from advanced_alchemy.extensions.litestar.service import SQLAlchemyAsyncRepositoryService
Benefits
- Better IDE Support: IDEs can provide better autocomplete and import suggestions
- More Intuitive: Matches standard Python module import patterns
- Easier Migration: Simplifies migration from other SQLAlchemy integrations
- Documentation: Cleaner in documentation and examples
Context
This came up during the Litestar v3.0 migration where we're moving from litestar.plugins.sqlalchemy
to direct advanced_alchemy.extensions.litestar
imports. The current attribute-based approach works but requires workarounds for clean imports.
Solution Options
Option 1: Backwards Compatible Approach
Create actual Python module files for the submodules while maintaining current API compatibility.
Structure:
advanced_alchemy/extensions/litestar/
├── __init__.py
├── repository.py # or repository/__init__.py
├── base.py # or base/__init__.py
├── service.py # or service/__init__.py
└── (other submodule files)
Implementation:
# advanced_alchemy/extensions/litestar/repository.py
from advanced_alchemy.repository import (
SQLAlchemyAsyncRepository,
SQLAlchemySyncRepository,
# ... other repository classes
)
# advanced_alchemy/extensions/litestar/__init__.py
from . import repository, base, service # Import the new modules
# The attributes are now the actual modules, maintaining compatibility
Benefits:
- ✅ Direct imports work:
from advanced_alchemy.extensions.litestar.repository import SQLAlchemyAsyncRepository
- ✅ Backward compatibility: Existing
aa_litestar.repository.SQLAlchemyAsyncRepository
still works - ✅ IDE support: Full autocomplete and import suggestions
- ✅ No breaking changes: Existing code continues to work
Option 2: Clean Approach (Recommended)
Create a cleaner module structure without backwards compatibility concerns.
Structure:
advanced_alchemy/extensions/litestar/
├── __init__.py # Only imports the main classes directly
├── repository/
│ └── __init__.py # Re-exports repository classes
├── base/
│ └── __init__.py # Re-exports base classes
├── service/
│ └── __init__.py # Re-exports service classes
├── dto/
│ └── __init__.py # Re-exports DTO classes
└── plugins/
└── __init__.py # Re-exports plugin classes
Implementation:
# advanced_alchemy/extensions/litestar/__init__.py
from advanced_alchemy.config import SQLAlchemyAsyncConfig, SQLAlchemySyncConfig
from .plugins import SQLAlchemyPlugin, SQLAlchemyInitPlugin, SQLAlchemySerializationPlugin
from .dto import SQLAlchemyDTO
# Don't re-export submodules as attributes
# advanced_alchemy/extensions/litestar/repository/__init__.py
from advanced_alchemy.repository import (
SQLAlchemyAsyncRepository,
SQLAlchemySyncRepository,
# ... all repository classes
)
Usage:
# Main classes (most common)
from advanced_alchemy.extensions.litestar import SQLAlchemyPlugin, SQLAlchemyAsyncConfig
# Specialized classes (explicit imports)
from advanced_alchemy.extensions.litestar.repository import SQLAlchemyAsyncRepository
from advanced_alchemy.extensions.litestar.base import BigIntAuditBase
Benefits:
- ✅ Clean namespace: Main module only contains essential classes
- ✅ Explicit imports: Users are intentional about imports
- ✅ Better organization: Related classes grouped logically
- ✅ IDE-friendly: Perfect autocomplete and import suggestions
- ✅ Maintainable: Clear module responsibilities
- ✅ Discoverable: Natural exploration of submodules
Migration Impact:
# OLD
from advanced_alchemy.extensions.litestar import repository
SQLAlchemyAsyncRepository = repository.SQLAlchemyAsyncRepository
# NEW
from advanced_alchemy.extensions.litestar.repository import SQLAlchemyAsyncRepository
Recommendation
Option 2 (Clean Approach) is recommended for better long-term maintainability and standard Python patterns, but Option 1 (Backwards Compatible) could be used if breaking changes are not acceptable in the current release cycle.
Both approaches would significantly improve the developer experience and IDE support compared to the current implementation.