"""Docker container enrichment: health, exit/restart, grouping, I/O counters Adds the fields the agent (≥1.4.0) now reports per container beyond the basic state: health status, exit code, OOM flag, compose/swarm grouping labels, and cumulative network/block I/O counters. Additive columns — no data loss, so no DROP+recreate needed here. Revision ID: docker_003_container_enrichment Revises: docker_002_host_scoped Create Date: 2026-06-19 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa revision: str = "docker_003_container_enrichment" down_revision: Union[str, None] = "docker_002_host_scoped" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.add_column("docker_containers", sa.Column("health", sa.String(16), nullable=True)) op.add_column("docker_containers", sa.Column("exit_code", sa.Integer, nullable=True)) op.add_column("docker_containers", sa.Column("oom_killed", sa.Boolean, nullable=False, server_default=sa.false())) op.add_column("docker_containers", sa.Column("compose_project", sa.String(255), nullable=True)) op.add_column("docker_containers", sa.Column("service_name", sa.String(255), nullable=True)) op.add_column("docker_containers", sa.Column("task_id", sa.String(64), nullable=True)) op.add_column("docker_containers", sa.Column("node_id", sa.String(64), nullable=True)) op.add_column("docker_containers", sa.Column("net_rx_bytes", sa.BigInteger, nullable=True)) op.add_column("docker_containers", sa.Column("net_tx_bytes", sa.BigInteger, nullable=True)) op.add_column("docker_containers", sa.Column("blk_read_bytes", sa.BigInteger, nullable=True)) op.add_column("docker_containers", sa.Column("blk_write_bytes", sa.BigInteger, nullable=True)) def downgrade() -> None: for col in ("blk_write_bytes", "blk_read_bytes", "net_tx_bytes", "net_rx_bytes", "node_id", "task_id", "service_name", "compose_project", "oom_killed", "exit_code", "health"): op.drop_column("docker_containers", col)