import enum from sqlalchemy import (Column, Integer, String, Date, Enum, Boolean, DECIMAL, Text, TIMESTAMP, ForeignKey, Table) from sqlalchemy.sql import func from sqlalchemy.orm import relationship from .database import Base # ============================================================================= # DEFINIZIONE DEGLI ENUM # ============================================================================= class GenderType(str, enum.Enum): male = "male" female = "female" other = "other" class ShoeSystemType(str, enum.Enum): EU = "EU" US = "US" UK = "UK" class BraSystemType(str, enum.Enum): US = "US" UK = "UK" EU = "EU" FR = "FR" AU = "AU" IT = "IT" JP = "JP" # NUOVO ENUM: Tipo di intervento estetico class SurgeryType(str, enum.Enum): breast_reduction = "breast_reduction" breast_augmentation = "breast_augmentation" breast_lift = "breast_lift" rhinoplasty = "rhinoplasty" other = "other" # ============================================================================= # TABELLE DI ASSOCIAZIONE (PER RELAZIONI MOLTI-A-MOLTI) # ============================================================================= celebrity_professions = Table( "celebrity_professions", Base.metadata, Column("celebrity_id", Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), primary_key=True), Column("profession_id", Integer, ForeignKey("professions.id", ondelete="CASCADE"), primary_key=True), ) celebrity_studios = Table( "celebrity_studios", Base.metadata, Column("celebrity_id", Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), primary_key=True), Column("studio_id", Integer, ForeignKey("studios.id", ondelete="CASCADE"), primary_key=True), ) video_performers = Table( "video_performers", Base.metadata, Column("video_id", Integer, ForeignKey("videos.id", ondelete="CASCADE"), primary_key=True), Column("celebrity_id", Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), primary_key=True), ) # ============================================================================= # MODELLI PRINCIPALI # ============================================================================= class Celebrity(Base): __tablename__ = "celebrities" id = Column(Integer, primary_key=True, index=True) name = Column(String, unique=True, nullable=False, index=True) gender = Column(Enum(GenderType), nullable=False) birth_date = Column(Date, nullable=True) birth_place = Column(String, nullable=True) nationality = Column(String, nullable=True) ethnicity = Column(String, nullable=True) sexuality = Column(String, nullable=True) hair_color = Column(String, nullable=True) eye_color = Column(String, nullable=True) height_cm = Column(Integer, nullable=True) weight_kg = Column(Integer, nullable=True) body_type = Column(String, nullable=True) bust_cm = Column(Integer, nullable=True) waist_cm = Column(Integer, nullable=True) hips_cm = Column(Integer, nullable=True) chest_circumference_cm = Column(Integer, nullable=True) bra_band_size = Column(Integer, nullable=True) bra_cup_size = Column(String, nullable=True) bra_size_system = Column(Enum(BraSystemType), nullable=True) boobs_are_natural = Column(Boolean, nullable=True) shoe_size = Column(DECIMAL(4, 1), nullable=True) shoe_size_system = Column(Enum(ShoeSystemType), nullable=True) biography = Column(Text, nullable=True) official_website = Column(String, nullable=True) profile_image_id = Column(Integer, ForeignKey("images.id", ondelete="SET NULL"), nullable=True) created_at = Column(TIMESTAMP(timezone=True), server_default=func.now()) updated_at = Column(TIMESTAMP(timezone=True), default=func.now(), onupdate=func.now()) # RELAZIONI profile_image = relationship("Image", foreign_keys=[profile_image_id]) # Relazioni Uno-a-Molti (Una celebrità ha molti...) images = relationship("Image", back_populates="celebrity", foreign_keys="Image.celebrity_id", cascade="all, delete-orphan") tattoos = relationship("Tattoo", back_populates="celebrity", cascade="all, delete-orphan") aliases = relationship("CelebrityAlias", back_populates="celebrity", cascade="all, delete-orphan") activity_periods = relationship("ActivityPeriod", back_populates="celebrity", cascade="all, delete-orphan") cosmetic_surgeries = relationship("CosmeticSurgery", back_populates="celebrity", cascade="all, delete-orphan") social_media = relationship("SocialMediaAccount", back_populates="celebrity", cascade="all, delete-orphan") external_links = relationship("ExternalLink", back_populates="celebrity", cascade="all, delete-orphan") # Relazioni Molti-a-Molti professions = relationship("Profession", secondary=celebrity_professions, back_populates="celebrities") studios = relationship("Studio", secondary=celebrity_studios, back_populates="celebrities") videos = relationship("Video", secondary=video_performers, back_populates="performers") # ============================================================================= # MODELLI "LOOKUP" (PROFESSIONI, STUDIOS) # ============================================================================= class Profession(Base): __tablename__ = "professions" id = Column(Integer, primary_key=True) name = Column(String, unique=True, nullable=False) celebrities = relationship("Celebrity", secondary=celebrity_professions, back_populates="professions") class Studio(Base): __tablename__ = "studios" id = Column(Integer, primary_key=True) name = Column(String, unique=True, nullable=False) celebrities = relationship("Celebrity", secondary=celebrity_studios, back_populates="studios") videos = relationship("Video", back_populates="studio") class Video(Base): __tablename__ = "videos" id = Column(Integer, primary_key=True) title = Column(String, nullable=False) release_date = Column(Date) studio_id = Column(Integer, ForeignKey("studios.id")) description = Column(Text) url_preview = Column(String) studio = relationship("Studio", back_populates="videos") performers = relationship("Celebrity", secondary=video_performers, back_populates="videos") # ============================================================================= # MODELLI SATELLITE (LEGATI A CELEBRITY CON RELAZIONE 1-A-MOLTI) # ============================================================================= class Image(Base): __tablename__ = "images" id = Column(Integer, primary_key=True, index=True) celebrity_id = Column(Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), nullable=False) file_path = Column(String, nullable=False) caption = Column(Text, nullable=True) uploaded_at = Column(TIMESTAMP(timezone=True), server_default=func.now()) celebrity = relationship("Celebrity", back_populates="images", foreign_keys=[celebrity_id]) class Tattoo(Base): __tablename__ = "tattoos" id = Column(Integer, primary_key=True) celebrity_id = Column(Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), nullable=False) description = Column(String, nullable=False) body_location = Column(String) celebrity = relationship("Celebrity", back_populates="tattoos") class CelebrityAlias(Base): __tablename__ = "celebrity_aliases" id = Column(Integer, primary_key=True) celebrity_id = Column(Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), nullable=False) alias_name = Column(String, nullable=False) celebrity = relationship("Celebrity", back_populates="aliases") class ActivityPeriod(Base): __tablename__ = "activity_periods" id = Column(Integer, primary_key=True) celebrity_id = Column(Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), nullable=False) start_year = Column(Integer, nullable=False) end_year = Column(Integer, nullable=True) notes = Column(Text) celebrity = relationship("Celebrity", back_populates="activity_periods") class CosmeticSurgery(Base): __tablename__ = "cosmetic_surgeries" id = Column(Integer, primary_key=True) celebrity_id = Column(Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), nullable=False) surgery_type = Column(Enum(SurgeryType), nullable=False) surgery_date = Column(Date) new_bra_band_size = Column(Integer) new_bra_cup_size = Column(String) new_bra_size_system = Column(Enum(BraSystemType)) notes = Column(Text) created_at = Column(TIMESTAMP(timezone=True), server_default=func.now()) celebrity = relationship("Celebrity", back_populates="cosmetic_surgeries") class SocialMediaAccount(Base): __tablename__ = "social_media_accounts" id = Column(Integer, primary_key=True) celebrity_id = Column(Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), nullable=False) platform = Column(String, nullable=False) url = Column(String, unique=True, nullable=False) follower_count = Column(Integer) last_checked_date = Column(Date) celebrity = relationship("Celebrity", back_populates="social_media") class ExternalLink(Base): __tablename__ = "external_links" id = Column(Integer, primary_key=True) celebrity_id = Column(Integer, ForeignKey("celebrities.id", ondelete="CASCADE"), nullable=False) url = Column(String, nullable=False) title = Column(String) source_website = Column(String) publication_date = Column(Date) celebrity = relationship("Celebrity", back_populates="external_links")