Skip to content

Conversation

@njg7194
Copy link

@njg7194 njg7194 commented Feb 1, 2026

Summary

This PR adds SQLAlchemy models as a new contrib module, mirroring the existing Django models. This addresses #75.

Changes

  • chancy/contrib/sqlalchemy/init.py - Module documentation
  • chancy/contrib/sqlalchemy/models.py - SQLAlchemy models for Job, Worker, and Queue tables
  • tests/contrib/sqlalchemy/test_models.py - Integration tests

Features

  • Full SQLAlchemy 2.0 style with mapped_column and Mapped types
  • PostgreSQL-specific types (JSONB, ARRAY, UUID)
  • Table prefix customization via CHANCY_PREFIX environment variable
  • Comprehensive docstrings with usage examples
  • Unmanaged models (Chancy handles migrations)

Usage Example

from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session
from chancy.contrib.sqlalchemy.models import Job, Queue, Worker

engine = create_engine("postgresql://...")

with Session(engine) as session:
    # Get all pending jobs
    pending_jobs = session.execute(
        select(Job).where(Job.state == "pending")
    ).scalars().all()
    
    # Get all active queues
    active_queues = session.execute(
        select(Queue).where(Queue.state == "active")
    ).scalars().all()

Closes #75

This adds a new contrib module with SQLAlchemy models that mirror the
existing Django models. Users can now query Chancy data using SQLAlchemy's
ORM without managing the table schema.

New files:
- chancy/contrib/sqlalchemy/__init__.py - Module docstring
- chancy/contrib/sqlalchemy/models.py - Job, Worker, Queue models
- tests/contrib/sqlalchemy/test_models.py - Integration tests

The models support:
- Table prefix customization via CHANCY_PREFIX environment variable
- Full SQLAlchemy 2.0 style with mapped_column and Mapped types
- PostgreSQL-specific types (JSONB, ARRAY, UUID)
- Comprehensive docstrings with usage examples

Closes TkTech#75
@TkTech TkTech self-requested a review February 2, 2026 00:36
@TkTech TkTech added the enhancement New feature or request label Feb 2, 2026
@TkTech TkTech changed the base branch from main to 26_ux February 2, 2026 00:36
Copy link
Contributor

@PaulM5406 PaulM5406 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @njg7194 for the PR. I will let @TkTech review the implementation details more thoroughly. Reading it, I have a few small comments.


with Session(engine) as session:
# Get all pending jobs
pending_jobs = session.query(Job).filter(Job.state == "pending").all()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this documentation uses the former SQLA syntaxe, i.e. session.query.
test_models.py uses modern syntaxe session.execute though.

PG_UUID(as_uuid=True),
primary_key=True,
)
queue: Mapped[str] = mapped_column(Text, nullable=False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: For the whole file, nullable can be inferred from the type.

Suggested change
queue: Mapped[str] = mapped_column(Text, nullable=False)
queue: Mapped[str] = mapped_column(Text)

If Optional is used, nullable=True is inferred.

"""

__tablename__ = f"{PREFIX}jobs"
__table_args__ = {"extend_existing": True}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is really useful ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: sqlalchemy models

3 participants