115 lines
4.8 KiB
Python
115 lines
4.8 KiB
Python
from datetime import datetime
|
|
|
|
from sqlalchemy import (
|
|
Boolean,
|
|
DateTime,
|
|
Enum,
|
|
ForeignKey,
|
|
Index,
|
|
Integer,
|
|
String,
|
|
Text,
|
|
func,
|
|
)
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from app.db.base import Base
|
|
from app.models.enums import EventStatus, EventType, TicketTypeStatus
|
|
|
|
|
|
class Venue(Base):
|
|
__tablename__ = "venues"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
slug: Mapped[str] = mapped_column(String(120), unique=True, index=True)
|
|
name: Mapped[str] = mapped_column(String(200))
|
|
area: Mapped[str] = mapped_column(String(120))
|
|
city: Mapped[str] = mapped_column(String(80), default="Bengaluru")
|
|
address: Mapped[str] = mapped_column(String(512))
|
|
map_url: Mapped[str | None] = mapped_column(String(512), nullable=True)
|
|
description: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
onupdate=func.now(),
|
|
)
|
|
|
|
events: Mapped[list["Event"]] = relationship("Event", back_populates="venue")
|
|
|
|
|
|
class Event(Base):
|
|
__tablename__ = "events"
|
|
__table_args__ = (
|
|
Index("ix_events_status_starts_at", "status", "starts_at"),
|
|
Index("ix_events_category_status", "category", "status"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
slug: Mapped[str] = mapped_column(String(200), unique=True, index=True)
|
|
title: Mapped[str] = mapped_column(String(240))
|
|
category: Mapped[EventType] = mapped_column(Enum(EventType), index=True)
|
|
status: Mapped[EventStatus] = mapped_column(Enum(EventStatus), default=EventStatus.draft, index=True)
|
|
venue_id: Mapped[int] = mapped_column(ForeignKey("venues.id", ondelete="RESTRICT"), index=True)
|
|
description: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
starts_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), index=True)
|
|
ends_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
is_featured: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
cover_image_url: Mapped[str | None] = mapped_column(String(1024), nullable=True)
|
|
cover_image_alt: Mapped[str | None] = mapped_column(String(300), nullable=True)
|
|
meta_description: Mapped[str | None] = mapped_column(String(320), nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
onupdate=func.now(),
|
|
)
|
|
|
|
venue: Mapped["Venue"] = relationship("Venue", back_populates="events")
|
|
media: Mapped[list["EventMedia"]] = relationship(
|
|
"EventMedia",
|
|
back_populates="event",
|
|
cascade="all, delete-orphan",
|
|
order_by="EventMedia.sort_order",
|
|
)
|
|
ticket_types: Mapped[list["TicketType"]] = relationship(
|
|
"TicketType",
|
|
back_populates="event",
|
|
cascade="all, delete-orphan",
|
|
order_by="TicketType.sort_order",
|
|
)
|
|
|
|
|
|
class EventMedia(Base):
|
|
__tablename__ = "event_media"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
event_id: Mapped[int] = mapped_column(ForeignKey("events.id", ondelete="CASCADE"), index=True)
|
|
image_url: Mapped[str] = mapped_column(String(1024))
|
|
alt_text: Mapped[str | None] = mapped_column(String(300), nullable=True)
|
|
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
|
|
event: Mapped["Event"] = relationship("Event", back_populates="media")
|
|
|
|
|
|
class TicketType(Base):
|
|
__tablename__ = "ticket_types"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
event_id: Mapped[int] = mapped_column(ForeignKey("events.id", ondelete="CASCADE"), index=True)
|
|
name: Mapped[str] = mapped_column(String(120))
|
|
description: Mapped[str | None] = mapped_column(String(512), nullable=True)
|
|
price_paise: Mapped[int] = mapped_column(Integer)
|
|
quantity_total: Mapped[int] = mapped_column(Integer)
|
|
quantity_sold: Mapped[int] = mapped_column(Integer, default=0)
|
|
status: Mapped[TicketTypeStatus] = mapped_column(Enum(TicketTypeStatus), default=TicketTypeStatus.active)
|
|
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
onupdate=func.now(),
|
|
)
|
|
|
|
event: Mapped["Event"] = relationship("Event", back_populates="ticket_types")
|