82 lines
3.8 KiB
Python
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"))
|