Faster track selection diaglog

Use better query to load last_played times along with tracks
This commit is contained in:
Keith Edmunds 2023-10-04 01:50:51 +01:00
parent b2f826dfcc
commit bb700d26f1
2 changed files with 22 additions and 14 deletions

View File

@ -25,6 +25,7 @@ from sqlalchemy import (
from sqlalchemy.orm import ( from sqlalchemy.orm import (
declarative_base, declarative_base,
joinedload,
relationship, relationship,
) )
from sqlalchemy.orm.exc import ( from sqlalchemy.orm.exc import (
@ -133,7 +134,7 @@ class Playdates(Base):
__tablename__ = "playdates" __tablename__ = "playdates"
id: int = Column(Integer, primary_key=True, autoincrement=True) id: int = Column(Integer, primary_key=True, autoincrement=True)
lastplayed = Column(DateTime, index=True, default=None) lastplayed: datetime = Column(DateTime, index=True)
track_id = Column(Integer, ForeignKey("tracks.id")) track_id = Column(Integer, ForeignKey("tracks.id"))
track: "Tracks" = relationship("Tracks", back_populates="playdates") track: "Tracks" = relationship("Tracks", back_populates="playdates")
@ -638,9 +639,9 @@ class Tracks(Base):
path: str = Column(String(2048), index=False, nullable=False, unique=True) path: str = Column(String(2048), index=False, nullable=False, unique=True)
mtime = Column(Float, index=True) mtime = Column(Float, index=True)
bitrate = Column(Integer, nullable=True, default=None) bitrate = Column(Integer, nullable=True, default=None)
playlistrows: PlaylistRows = relationship("PlaylistRows", back_populates="track") playlistrows: List[PlaylistRows] = relationship("PlaylistRows", back_populates="track")
playlists = association_proxy("playlistrows", "playlist") playlists = association_proxy("playlistrows", "playlist")
playdates: Playdates = relationship("Playdates", back_populates="track") playdates: List[Playdates] = relationship("Playdates", back_populates="track")
def __repr__(self) -> str: def __repr__(self) -> str:
return ( return (
@ -715,15 +716,22 @@ class Tracks(Base):
@classmethod @classmethod
def search_titles(cls, session: scoped_session, text: str) -> List["Tracks"]: def search_titles(cls, session: scoped_session, text: str) -> List["Tracks"]:
"""Search case-insenstively for titles containing str""" """
Search case-insenstively for titles containing str
The query performs an outer join with 'joinedload' to populate the results
from the Playdates table at the same time. unique() needed; see
https://docs.sqlalchemy.org/en/20/orm/queryguide/relationships.html#joined-eager-loading
"""
return ( return (
session.execute( session.execute(
select(cls) select(cls)
.join(Playdates, isouter=True) .options(joinedload(Tracks.playdates))
.where(cls.title.like(f"{text}%")) .where(cls.title.like(f"{text}%"))
.group_by(cls.title) .group_by(cls.title)
.order_by(cls.title) .order_by(cls.title)
) )
.scalars() .scalars()
.unique()
.all() .all()
) )

View File

@ -1937,7 +1937,9 @@ class DbDialog(QDialog):
return return
if track: if track:
self.musicmuster.visible_playlist_tab().insert_track(self.session, track, note) self.musicmuster.visible_playlist_tab().insert_track(
self.session, track, note
)
else: else:
self.musicmuster.visible_playlist_tab().insert_header(self.session, note) self.musicmuster.visible_playlist_tab().insert_header(self.session, note)
@ -1956,19 +1958,17 @@ class DbDialog(QDialog):
if matches: if matches:
for track in matches: for track in matches:
last_played = None last_played = None
show_last_played = False last_playdate = max(
if len(matches) < 20: track.playdates, key=lambda p: p.lastplayed, default=None
show_last_played = True )
last_playdate = max(track.playdates, key=lambda p: p.lastplayed, default=None) if last_playdate:
if last_playdate: last_played = last_playdate.lastplayed
last_played = last_playdate.lastplayed
t = QListWidgetItem() t = QListWidgetItem()
track_text = ( track_text = (
f"{track.title} - {track.artist} " f"{track.title} - {track.artist} "
f"[{helpers.ms_to_mmss(track.duration)}] " f"[{helpers.ms_to_mmss(track.duration)}] "
f"({helpers.get_relative_date(last_played)})"
) )
if show_last_played:
track_text += f"({helpers.get_relative_date(last_played)})"
t.setText(track_text) t.setText(track_text)
t.setData(Qt.ItemDataRole.UserRole, track) t.setData(Qt.ItemDataRole.UserRole, track)
self.ui.matchList.addItem(t) self.ui.matchList.addItem(t)