# #region MappingModels [C:5] [TYPE Module] [SEMANTICS sqlalchemy, mapping, model, schema, resource-type] # # @BRIEF Defines the database schema for environment metadata and database mappings using SQLAlchemy. # @LAYER Domain # @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy] # # @INVARIANT All primary keys are UUID strings. # CONSTRAINT: source_env_id and target_env_id must be valid environment IDs. # @PRE Database engine initialized # @POST Mapping ORM models registered with UUID primary keys # @SIDE_EFFECT Defines environment/database/resource mapping tables # @DATA_CONTRACT MappingData -> MappingRecord import enum import uuid from sqlalchemy import Boolean, Column, DateTime, Enum as SQLEnum, ForeignKey, String from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.sql import func # #region Base [C:1] [TYPE Class] # @BRIEF SQLAlchemy declarative base for all domain models. # #endregion Base Base = declarative_base() # #region ResourceType [C:1] [TYPE Class] # @BRIEF Enumeration of possible Superset resource types for ID mapping. class ResourceType(str, enum.Enum): CHART = "chart" DATASET = "dataset" DASHBOARD = "dashboard" # #endregion ResourceType # #region MigrationStatus [C:1] [TYPE Class] # @BRIEF Enumeration of possible migration job statuses. class MigrationStatus(enum.Enum): PENDING = "PENDING" RUNNING = "RUNNING" COMPLETED = "COMPLETED" FAILED = "FAILED" AWAITING_MAPPING = "AWAITING_MAPPING" # #endregion MigrationStatus # #region Environment [C:3] [TYPE Class] # @BRIEF Represents a Superset instance environment. # @RELATION DEPENDS_ON -> MappingModels class Environment(Base): __tablename__ = "environments" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) name = Column(String, nullable=False) url = Column(String, nullable=False) credentials_id = Column(String, nullable=False) # #endregion Environment # #region DatabaseMapping [C:3] [TYPE Class] # @BRIEF Represents a mapping between source and target databases. class DatabaseMapping(Base): __tablename__ = "database_mappings" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) source_env_id = Column(String, ForeignKey("environments.id", ondelete="CASCADE"), nullable=False) target_env_id = Column(String, ForeignKey("environments.id", ondelete="CASCADE"), nullable=False) source_db_uuid = Column(String, nullable=False) target_db_uuid = Column(String, nullable=False) source_db_name = Column(String, nullable=False) target_db_name = Column(String, nullable=False) engine = Column(String, nullable=True) # #endregion DatabaseMapping # #region MigrationJob [C:2] [TYPE Class] # @BRIEF Represents a single migration execution job. class MigrationJob(Base): __tablename__ = "migration_jobs" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) source_env_id = Column(String, ForeignKey("environments.id", ondelete="CASCADE"), nullable=False) target_env_id = Column(String, ForeignKey("environments.id", ondelete="CASCADE"), nullable=False) status = Column(SQLEnum(MigrationStatus), default=MigrationStatus.PENDING) replace_db = Column(Boolean, default=False) created_at = Column(DateTime(timezone=True), server_default=func.now()) # #endregion MigrationJob # #region ResourceMapping [C:3] [TYPE Class] # @BRIEF Maps a universal UUID for a resource to its actual ID on a specific environment. # @TEST_DATA: resource_mapping_record -> {'environment_id': 'prod-env-1', 'resource_type': 'chart', 'uuid': '123e4567-e89b-12d3-a456-426614174000', 'remote_integer_id': '42'} # @RELATION DEPENDS_ON -> MappingModels class ResourceMapping(Base): __tablename__ = "resource_mappings" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) environment_id = Column(String, ForeignKey("environments.id", ondelete="CASCADE"), nullable=False) resource_type = Column(SQLEnum(ResourceType), nullable=False) uuid = Column(String, nullable=False) remote_integer_id = Column(String, nullable=False) # Stored as string to handle potentially large or composite IDs safely, though Superset usually uses integers. resource_name = Column(String, nullable=True) # Used for UI display last_synced_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) # #endregion ResourceMapping # #endregion MappingModels