feat: Enhance timestamp management in BaseModel and PlaylistRepository; add automatic updates and improve code readability
All checks were successful
Backend CI / lint (push) Successful in 9m21s
Backend CI / test (push) Successful in 4m0s

This commit is contained in:
JSC
2025-08-16 00:19:53 +02:00
parent b691649f7e
commit 4cec3b9d18
4 changed files with 38 additions and 3 deletions

View File

@@ -1,6 +1,9 @@
from datetime import UTC, datetime from datetime import UTC, datetime
from typing import Any
from sqlalchemy import event from sqlalchemy import event
from sqlalchemy.engine import Connection
from sqlalchemy.orm import Mapper
from sqlmodel import Field, SQLModel from sqlmodel import Field, SQLModel
@@ -16,6 +19,8 @@ class BaseModel(SQLModel):
# SQLAlchemy event listener to automatically update updated_at timestamp # SQLAlchemy event listener to automatically update updated_at timestamp
@event.listens_for(BaseModel, "before_update", propagate=True) @event.listens_for(BaseModel, "before_update", propagate=True)
def update_timestamp(mapper, connection, target): def update_timestamp(
mapper: Mapper[Any], connection: Connection, target: BaseModel, # noqa: ARG001
) -> None:
"""Automatically set updated_at timestamp before update operations.""" """Automatically set updated_at timestamp before update operations."""
target.updated_at = datetime.now(UTC) target.updated_at = datetime.now(UTC)

View File

@@ -35,3 +35,5 @@ class PlaylistSound(BaseModel, table=True):
# relationships # relationships
playlist: "Playlist" = Relationship(back_populates="playlist_sounds") playlist: "Playlist" = Relationship(back_populates="playlist_sounds")
sound: "Sound" = Relationship(back_populates="playlist_sounds") sound: "Sound" = Relationship(back_populates="playlist_sounds")

View File

@@ -114,7 +114,8 @@ class BaseRepository[ModelType]:
for field, value in update_data.items(): for field, value in update_data.items():
setattr(entity, field, value) setattr(entity, field, value)
# The updated_at timestamp will be automatically set by the SQLAlchemy event listener # The updated_at timestamp will be automatically set by the SQLAlchemy
# event listener
self.session.add(entity) self.session.add(entity)
await self.session.commit() await self.session.commit()
await self.session.refresh(entity) await self.session.refresh(entity)

View File

@@ -1,5 +1,6 @@
"""Playlist repository for database operations.""" """Playlist repository for database operations."""
from datetime import UTC, datetime
from enum import Enum from enum import Enum
from sqlalchemy import func, update from sqlalchemy import func, update
@@ -42,6 +43,23 @@ class PlaylistRepository(BaseRepository[Playlist]):
"""Initialize the playlist repository.""" """Initialize the playlist repository."""
super().__init__(Playlist, session) super().__init__(Playlist, session)
async def _update_playlist_timestamp(self, playlist_id: int) -> None:
"""Update the playlist's updated_at timestamp."""
try:
update_stmt = (
update(Playlist)
.where(Playlist.id == playlist_id)
.values(updated_at=datetime.now(UTC))
)
await self.session.exec(update_stmt)
# Note: No commit here - let the calling method handle transaction
# management
except Exception:
logger.exception(
"Failed to update playlist timestamp for playlist: %s", playlist_id,
)
raise
async def get_by_name(self, name: str) -> Playlist | None: async def get_by_name(self, name: str) -> Playlist | None:
"""Get a playlist by name.""" """Get a playlist by name."""
try: try:
@@ -133,7 +151,8 @@ class PlaylistRepository(BaseRepository[Playlist]):
return list(result.all()) return list(result.all())
except Exception: except Exception:
logger.exception( logger.exception(
"Failed to get playlist sound entries for playlist: %s", playlist_id, "Failed to get playlist sound entries for playlist: %s",
playlist_id,
) )
raise raise
@@ -188,6 +207,9 @@ class PlaylistRepository(BaseRepository[Playlist]):
position=position, position=position,
) )
self.session.add(playlist_sound) self.session.add(playlist_sound)
# Update playlist timestamp before commit
await self._update_playlist_timestamp(playlist_id)
await self.session.commit() await self.session.commit()
await self.session.refresh(playlist_sound) await self.session.refresh(playlist_sound)
except Exception: except Exception:
@@ -219,6 +241,9 @@ class PlaylistRepository(BaseRepository[Playlist]):
if playlist_sound: if playlist_sound:
await self.session.delete(playlist_sound) await self.session.delete(playlist_sound)
# Update playlist timestamp before commit
await self._update_playlist_timestamp(playlist_id)
await self.session.commit() await self.session.commit()
logger.info("Removed sound %s from playlist %s", sound_id, playlist_id) logger.info("Removed sound %s from playlist %s", sound_id, playlist_id)
except Exception: except Exception:
@@ -268,6 +293,8 @@ class PlaylistRepository(BaseRepository[Playlist]):
if playlist_sound: if playlist_sound:
playlist_sound.position = new_position playlist_sound.position = new_position
# Update playlist timestamp before commit
await self._update_playlist_timestamp(playlist_id)
await self.session.commit() await self.session.commit()
logger.info("Reordered sounds in playlist %s", playlist_id) logger.info("Reordered sounds in playlist %s", playlist_id)
except Exception: except Exception: