GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
66 lines
3.6 KiB
Python
66 lines
3.6 KiB
Python
"""Add resumable AOI parent and partition operations."""
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
from geoalchemy2 import Geometry
|
|
|
|
|
|
revision = "202607260001"
|
|
down_revision = "202607160001"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.create_table(
|
|
"aoi_operations",
|
|
sa.Column("id", sa.UUID(), primary_key=True),
|
|
sa.Column("project_id", sa.UUID(), sa.ForeignKey("projects.id", ondelete="CASCADE"), nullable=False),
|
|
sa.Column("area_id", sa.UUID(), sa.ForeignKey("areas.id", ondelete="SET NULL")),
|
|
sa.Column("parent_job_id", sa.UUID(), sa.ForeignKey("jobs.id", ondelete="SET NULL")),
|
|
sa.Column("operation_type", sa.String(128), nullable=False),
|
|
sa.Column("status", sa.String(32), nullable=False),
|
|
sa.Column("geometry", Geometry("MultiPolygon", srid=4326, spatial_index=False), nullable=False),
|
|
sa.Column("request_json", sa.JSON(), nullable=False),
|
|
sa.Column("plan_json", sa.JSON(), nullable=False),
|
|
sa.Column("result_json", sa.JSON()),
|
|
sa.Column("error_message", sa.Text()),
|
|
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
|
|
sa.Column("started_at", sa.DateTime(timezone=True)),
|
|
sa.Column("finished_at", sa.DateTime(timezone=True)),
|
|
sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
|
|
sa.CheckConstraint("status IN ('queued', 'running', 'partial', 'success', 'failed', 'cancelled')", name="ck_aoi_operations_status"),
|
|
)
|
|
op.create_index("ix_aoi_operations_project_status", "aoi_operations", ["project_id", "status"])
|
|
op.create_index("ix_aoi_operations_geometry", "aoi_operations", ["geometry"], postgresql_using="gist")
|
|
op.create_table(
|
|
"aoi_operation_partitions",
|
|
sa.Column("id", sa.UUID(), primary_key=True),
|
|
sa.Column("operation_id", sa.UUID(), sa.ForeignKey("aoi_operations.id", ondelete="CASCADE"), nullable=False),
|
|
sa.Column("child_job_id", sa.UUID(), sa.ForeignKey("jobs.id", ondelete="SET NULL")),
|
|
sa.Column("partition_key", sa.String(255), nullable=False),
|
|
sa.Column("provider_key", sa.String(120), nullable=False),
|
|
sa.Column("product_key", sa.String(120), nullable=False),
|
|
sa.Column("ordinal", sa.Integer(), nullable=False),
|
|
sa.Column("status", sa.String(32), nullable=False),
|
|
sa.Column("geometry", Geometry("MultiPolygon", srid=4326, spatial_index=False), nullable=False),
|
|
sa.Column("attempt_count", sa.Integer(), nullable=False, server_default="0"),
|
|
sa.Column("max_attempts", sa.Integer(), nullable=False, server_default="3"),
|
|
sa.Column("checkpoint_json", sa.JSON()),
|
|
sa.Column("result_json", sa.JSON()),
|
|
sa.Column("error_message", sa.Text()),
|
|
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
|
|
sa.Column("started_at", sa.DateTime(timezone=True)),
|
|
sa.Column("finished_at", sa.DateTime(timezone=True)),
|
|
sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
|
|
sa.CheckConstraint("status IN ('queued', 'running', 'success', 'failed', 'skipped')", name="ck_aoi_operation_partitions_status"),
|
|
sa.UniqueConstraint("operation_id", "partition_key", name="uq_aoi_operation_partition_key"),
|
|
)
|
|
op.create_index("ix_aoi_operation_partitions_operation_status", "aoi_operation_partitions", ["operation_id", "status"])
|
|
op.create_index("ix_aoi_operation_partitions_geometry", "aoi_operation_partitions", ["geometry"], postgresql_using="gist")
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_table("aoi_operation_partitions")
|
|
op.drop_table("aoi_operations")
|