diff --git a/backend/routers/shows.py b/backend/routers/shows.py index aeb5743..ae2d17a 100644 --- a/backend/routers/shows.py +++ b/backend/routers/shows.py @@ -34,82 +34,87 @@ def create_show( return db_show -def serialize_show(show: Show) -> ShowRead: +def serialize_show(show: Show) -> dict: """ - Robustly serialize a Show object to ShowRead, manually handling relationships - to avoid infinite recursion in Pydantic v2/SQLModel. + Robustly serialize a Show object to a dictionary. + Returning a dict breaks the link to SQLAlchemy ORM objects completely, + preventing Pydantic from triggering lazy loads or infinite recursion during validation. """ try: - # Base fields map directly - s_read = ShowRead( - id=show.id, - date=show.date, - slug=show.slug, - vertical_id=show.vertical_id, - venue_id=show.venue_id, - tour_id=show.tour_id, - notes=show.notes, - bandcamp_link=show.bandcamp_link, - nugs_link=show.nugs_link, - youtube_link=show.youtube_link, - # relisten_link is on model but not in ShowRead schema? - # Check schema again if needed, but safe to omit if not in schema - ) + # Base fields + data = { + "id": show.id, + "date": show.date, + "slug": show.slug, + "vertical_id": show.vertical_id, + "venue_id": show.venue_id, + "tour_id": show.tour_id, + "notes": show.notes, + "bandcamp_link": show.bandcamp_link, + "nugs_link": show.nugs_link, + "youtube_link": show.youtube_link, + "vertical": None, + "venue": None, + "tour": None, + "tags": [], + "performances": [] + } # Manually map relationships if present if show.vertical: try: - s_read.vertical = VerticalSimple( - id=show.vertical.id, - name=show.vertical.name, - slug=show.vertical.slug, - description=show.vertical.description, - logo_url=show.vertical.logo_url, - accent_color=show.vertical.accent_color - ) + data["vertical"] = { + "id": show.vertical.id, + "name": show.vertical.name, + "slug": show.vertical.slug, + "description": show.vertical.description, + "logo_url": show.vertical.logo_url, + "accent_color": show.vertical.accent_color + } except Exception as e: print(f"Error serializing vertical for show {show.id}: {e}") if show.venue: try: - s_read.venue = VenueRead( - id=show.venue.id, - name=show.venue.name, - slug=show.venue.slug, - city=show.venue.city, - state=show.venue.state, - country=show.venue.country, - capacity=show.venue.capacity, - notes=show.venue.notes - ) + data["venue"] = { + "id": show.venue.id, + "name": show.venue.name, + "slug": show.venue.slug, + "city": show.venue.city, + "state": show.venue.state, + "country": show.venue.country, + "capacity": show.venue.capacity, + "notes": show.venue.notes + } except Exception as e: print(f"Error serializing venue for show {show.id}: {e}") if show.tour: try: - s_read.tour = TourRead( - id=show.tour.id, - name=show.tour.name, - slug=show.tour.slug, - start_date=show.tour.start_date, - end_date=show.tour.end_date, - notes=show.tour.notes - ) + data["tour"] = { + "id": show.tour.id, + "name": show.tour.name, + "slug": show.tour.slug, + "start_date": show.tour.start_date, + "end_date": show.tour.end_date, + "notes": show.tour.notes + } except Exception as e: print(f"Error serializing tour for show {show.id}: {e}") - return s_read + return data except Exception as e: print(f"CRITICAL Error serializing show {show.id}: {e}") - # Return a minimal valid object or None? - # Safest to return basic info without relationships so user sees something - return ShowRead( - id=show.id, - date=show.date, - vertical_id=show.vertical_id, - slug=show.slug or "" - ) + # Return minimal valid dict + return { + "id": show.id, + "date": show.date, + "vertical_id": show.vertical_id, + "slug": show.slug or "", + "tags": [], + "performances": [] + } @router.get("/", response_model=PaginatedResponse[ShowRead]) def read_shows(