from typing import List from sqlalchemy import func from sqlalchemy.orm import Query, Session from config import config as _config def get_major_moves(session: Session, client, market: str, start_date: str, end_date: str) -> Query: """Get track entities difference between two dates. Using this method we can get major moves for tracks inside chart. Args: session (Session): DB session. client: SpotifyChart object. market: str market. start_date: str date in format %Y-%m-%d. end_date: str date in format %Y-%m-%d. """ query_for_yesterday = client._get_base_query(session, market, end_date).subquery() query_for_today = client._get_base_query(session, market, start_date).subquery() return ( session.query( query_for_today.c.track_id, query_for_today.c.track_name, query_for_today.c.position, query_for_today.c.artist_name, query_for_today.c.isrc, (query_for_today.c.position - func.min(query_for_yesterday.c.position)).label("moves"), ) .join(query_for_yesterday, query_for_yesterday.c.isrc == query_for_today.c.isrc) .group_by(query_for_today.c.isrc, query_for_today.c.position) .having( func.abs(query_for_today.c.position - func.min(query_for_yesterday.c.position)) >= _config.THRESHOLD_MAJOR_MOVES ) ) def process_moves_isrc_duplicates(query: Query) -> List: """Delete entities (set moves = 0 for MM == delete) for non top isrc position per chart per isrc. If there are some tracks with the same isrc in the chart non top items should be considered as not moving. Args: query: Moves query. Returns: List: Query result items. """ results = {} for track in query: key = f"{track.user_id}_{track.isrc}" saved_track = results.get(key) if saved_track is None or track.position < saved_track.position: results[key] = track return list(results.values())