""" Base Model Classes Mixins and base classes for all SQLAlchemy models """ import uuid from datetime import datetime from sqlalchemy import Column, DateTime from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.ext.declarative import declarative_base, declared_attr Base = declarative_base() class UUIDMixin: """Mixin that adds a UUID primary key""" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, index=True) class TimestampMixin: """Mixin that adds created_at and updated_at timestamps""" created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=True ) class TableNameMixin: """Mixin that auto-generates table name from class name""" @declared_attr def __tablename__(cls): # Convert CamelCase to snake_case name = cls.__name__ return "".join(["_" + c.lower() if c.isupper() else c for c in name]).lstrip( "_" )