Skip to content

Enhancement: Enable direct submodule imports for better IDE support #504

@cofin

Description

@cofin

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

  1. Better IDE Support: IDEs can provide better autocomplete and import suggestions
  2. More Intuitive: Matches standard Python module import patterns
  3. Easier Migration: Simplifies migration from other SQLAlchemy integrations
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions