Files
RAGcore-Public/alembic/versions/0008_jobs.py
T

82 lines
3.8 KiB
Python

"""Create PostgreSQL-backed jobs, attempts and transition events."""
from __future__ import annotations
import sqlalchemy as sa
from alembic import op
revision = "0008_jobs"
down_revision = "0007_user_grants"
branch_labels = None
depends_on = None
def upgrade() -> None:
op.execute(sa.text("CREATE SCHEMA IF NOT EXISTS jobs"))
op.create_table(
"jobs",
sa.Column("id", sa.Uuid(), primary_key=True),
sa.Column("job_key", sa.String(512), nullable=False, unique=True),
sa.Column("operation", sa.String(128), nullable=False),
sa.Column("target_key", sa.String(256), nullable=False),
sa.Column("profile_version", sa.String(128), nullable=False),
sa.Column("payload", sa.JSON(), nullable=False),
sa.Column("status", sa.String(32), nullable=False),
sa.Column("available_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("max_attempts", sa.Integer(), nullable=False),
sa.Column("attempt_count", sa.Integer(), nullable=False),
sa.Column("leased_by", sa.String(128), nullable=True),
sa.Column("lease_until", sa.DateTime(timezone=True), nullable=True),
sa.Column("trace_id", sa.String(128), nullable=False),
sa.Column("last_error_code", sa.String(128), nullable=True),
sa.Column("last_error_details", sa.JSON(), nullable=False),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
schema="jobs",
)
op.create_index(
"ix_jobs_ready", "jobs", ["status", "available_at", "lease_until"], schema="jobs"
)
op.create_table(
"attempts",
sa.Column("id", sa.Uuid(), primary_key=True),
sa.Column("job_id", sa.Uuid(), nullable=False),
sa.Column("attempt_number", sa.Integer(), nullable=False),
sa.Column("worker_id", sa.String(128), nullable=False),
sa.Column("status", sa.String(32), nullable=False),
sa.Column("leased_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("lease_until", sa.DateTime(timezone=True), nullable=False),
sa.Column("heartbeat_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("finished_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("error_code", sa.String(128), nullable=True),
sa.Column("error_details", sa.JSON(), nullable=False),
sa.ForeignKeyConstraint(["job_id"], ["jobs.jobs.id"], ondelete="CASCADE"),
sa.UniqueConstraint("job_id", "attempt_number", name="uq_jobs_attempt_number"),
schema="jobs",
)
op.create_index("ix_jobs_attempts_job", "attempts", ["job_id", "attempt_number"], schema="jobs")
op.create_table(
"events",
sa.Column("id", sa.Uuid(), primary_key=True),
sa.Column("job_id", sa.Uuid(), nullable=False),
sa.Column("event_type", sa.String(64), nullable=False),
sa.Column("occurred_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("trace_id", sa.String(128), nullable=False),
sa.Column("duration_ms", sa.Integer(), nullable=True),
sa.Column("error_code", sa.String(128), nullable=True),
sa.Column("details", sa.JSON(), nullable=False),
sa.ForeignKeyConstraint(["job_id"], ["jobs.jobs.id"], ondelete="CASCADE"),
schema="jobs",
)
op.create_index("ix_jobs_events_job_time", "events", ["job_id", "occurred_at"], schema="jobs")
def downgrade() -> None:
op.drop_index("ix_jobs_events_job_time", table_name="events", schema="jobs")
op.drop_table("events", schema="jobs")
op.drop_index("ix_jobs_attempts_job", table_name="attempts", schema="jobs")
op.drop_table("attempts", schema="jobs")
op.drop_index("ix_jobs_ready", table_name="jobs", schema="jobs")
op.drop_table("jobs", schema="jobs")
op.execute(sa.text("DROP SCHEMA IF EXISTS jobs"))