"""Models for tables related to Spotify.""" import enum from apollo_main_db.base import Base from sqlalchemy import BigInteger, Boolean, CHAR, Column, Date, DateTime, Enum, ForeignKey, Integer, SmallInteger, \ String, TIMESTAMP from sqlalchemy.orm import relationship class ViewPlaylistTypeEnum(enum.IntEnum): GTP = 0 HH = 1 NMF = 2 class MarketRankTypeEnum(enum.IntEnum): GENERAL = 0 HH = 1 NMF = 2 class SpotifyArtist(Base): """Spotify Artist. Attributes: id: Unique artist ID. name: Artist name. """ __tablename__ = 'tblSpotifyArtist' id = Column('ArtistId', String(255), primary_key=True) name = Column('Name', String(256)) def __str__(self) -> str: return 'Spotify Artist {} {}'.format(self.id, self.name) class SpotifyPlaylist(Base): """Spotify playlist. Spotify URI used for primary key. Attributes: uri: Spotify URI used for primary key. id: Unique playlist ID. name: Playlist name. description: Playlist description. user_name: Playlist creator name. country_code: Country code with possible null. duration: Length of playlist in seconds. track_count: Tracks count. update_timestamp: Auto-updated field. buzz_category_id: Playlist category like Sony or Spotify. followers: Playlists followers. """ __tablename__ = 'tblSpotifyPlaylist' uri = Column('PlaylistUri', String(255), primary_key=True) id = Column('PlaylistId', CHAR(22)) name = Column('Name', String(255)) description = Column('Description', String(5000)) user_name = Column('User', String(255)) country_code = Column('CountryCode', String(10)) duration = Column('Duration', Integer) track_count = Column('TrackCount', Integer) update_timestamp = Column('UpdateDate', TIMESTAMP()) removed = Column('Removed', Integer) image = Column('Image', String(255)) buzz_category_id = Column('BuzzCategoryId', Integer) followers = Column("Followers", Integer) def __str__(self) -> str: return 'Spotify playlist {}'.format(self.id) class PlaylistIgnoredPlaylist(Base): """Spotify playlist to ignore. Attributes: playlist_id: Playlist ID. music_service_id: Music service ID. """ __tablename__ = 'tblPlaylistIgnoredPlaylist' playlist_id = Column('PlaylistId', String(255), primary_key=True) music_service_id = Column('MusicServiceId', Integer, primary_key=True) def __str__(self) -> str: return 'Playlist ignored playlist {} {}'.format(self.playlist_id, self.music_service_id) class SpotifyTrack2(Base): """Spotify track. The name of the table is confusing. There is another table called tblSpotifyTrack in the database. But it is believed to be legacy and should not be used. Attributes: id: Unique Spotify track ID. name: Track name. isrc: International Standard Recording Code. This code is a unique identifier of a recording, but NOT of a track. The same recording can be released multiple times as tracks in different albums. Different tracks can share the same ISRC. """ __tablename__ = 'tblSpotifyTrack2' id = Column('TrackId', String(255), primary_key=True) name = Column('Name', String(256)) isrc = Column('ISRC', String(100)) duration = Column('Duration', Integer) popularity = Column('Popularity', Integer) def __str__(self) -> str: return 'Spotify track {}'.format(self.id) class SpotifyTrackAlbum(Base): """Album tracks. There is many-to-one relationship between tracks and albums. However, for unknown reason it is implemented as an intermediary table like many-to-many. Attributes: track_id: Track ID. album_id: Album ID. """ __tablename__ = 'tblSpotifyTrackAlbum' track_id = Column('TrackId', String(255), primary_key=True) album_id = Column('AlbumId', String(255), primary_key=True) def __str__(self) -> str: return 'Track {}, album {}'.format(self.track_id, self.album_id) class SpotifyTrackArtist(Base): """Track's artists. Many-to-many relationship between tracks and artists. Attributes: track_id: Track ID. artist_id: Artist ID. order: Zero-based position of artist in the list of track artists. If a track is performed by multiple artists, they are listed according to their significance in authorship. The primary artist goes first. """ __tablename__ = 'tblSpotifyTrackArtist' track_id = Column('TrackId', String(255), primary_key=True) artist_id = Column('ArtistId', String(255), primary_key=True) order = Column('ArtistOrder', Integer) def __str__(self) -> str: return 'Track {}, artist {}, order {}'.format(self.track_id, self.artist_id, self.order) class SpotifyPlaylistTrackList2(Base): """Link table between playlist and tracks. The name of the table is confusing. There is another table called tblSpotifyPlaylistTrackList in the database. But it is believed to be legacy and should not be used. Primary key combined from playlist_id + playlist_index Attributes: playlist_id: Playlist ID. track_id: Track ID. playlist_index: Track order in playlist. added_datetime: Datetime when its added. """ __tablename__ = "tblSpotifyPlaylistTrackList2" playlist_id = Column("PlaylistId", CHAR(22), primary_key=True) playlist_index = Column("PlaylistIndex", Integer(), primary_key=True) track_id = Column("TrackId", CHAR(22)) added_datetime = Column("Added", DateTime()) added_earliest_datetime = Column("EarliestAdded", DateTime()) timestamp = Column("Timestamp", TIMESTAMP) def __str__(self) -> str: return "Spotify relation playlist {} to track {}".format(self.playlist_id, self.track_id) class SpotifyPersonalizedPlaylistTrackList(Base): """Link table between playlist and tracks for personalized playlists and sony tracks only. Based on streams data, got from delphi api. Primary key combined from playlist_id + isrc Attributes: playlist_id: Playlist ID. isrc: Track ISRC track_id: Track ID. added_datetime: Datetime when the track was added to the playlist. updated: Timestamp of last data update. """ __tablename__ = 'tblSpotifyPersonalizedPlaylistTrackList' playlist_id = Column('PlaylistId', CHAR(50), primary_key=True) isrc = Column('Isrc', CHAR(50), primary_key=True) track_id = Column('TrackId', CHAR(50), nullable=False) added_datetime = Column('Added', DateTime(), nullable=False) updated = Column('Updated', TIMESTAMP()) def __str__(self) -> str: return 'Spotify relation personalized playlist {} to sony track {}'.format(self.playlist_id, self.isrc) class SpotifyPlaylistTrackListHistory2(Base): """Everyday popularity of playlist and tracks. The name of the table is confusing. There is another table called tblSpotifyPlaylistTrackListHistory. But it is believed to be legacy and should not be used. Primary key combined from playlist_id + date + playlist_index Attributes: playlist_id: Playlist ID. track_id: Track ID. playlist_index: Track order in playlist. date: Date when its added. """ __tablename__ = 'tblSpotifyPlaylistTrackListHistory2' playlist_id = Column('PlaylistId', CHAR(22), primary_key=True) date = Column('Date', Date(), primary_key=True) playlist_index = Column('PlaylistIndex', Integer(), primary_key=True) track_id = Column('TrackId', CHAR(22)) popularity = Column('Popularity', Integer) def __str__(self) -> str: return 'Spotify History Track {} on {}'.format(self.track_id, self.date) class SpotifyPlaylistTrackListHistory2Reduced(Base): """Everyday popularity of playlist and tracks. Primary key combined from playlist_id + date + playlist_index Attributes: playlist_id: Playlist ID. track_id: Track ID. playlist_index: Track order in playlist. date: Date when its added. """ __tablename__ = 'tblSpotifyPlaylistTracklistHistory2Reduced' playlist_id = Column('PlaylistId', CHAR(22), primary_key=True) date = Column('Date', Date(), primary_key=True) playlist_index = Column('PlaylistIndex', Integer(), primary_key=True) track_id = Column('TrackId', CHAR(22)) popularity = Column('Popularity', Integer) def __str__(self) -> str: return 'Spotify History Track {} on {}'.format(self.track_id, self.date) class SpotifyPlaylistTrackListHistoryDates2(Base): """Table with update's dates of SpotifyPlaylistTrackListHistory2. Attributes: playlist_id: Playlist ID. date: Date when it was updated. timestamp: Update timestamp. """ __tablename__ = 'tblSpotifyPlaylistTrackListHistoryDates2' playlist_id = Column('PlaylistId', CHAR(22), primary_key=True) date = Column('Date', Date(), primary_key=True, index=True) timestamp = Column('Timestamp', TIMESTAMP) def __str__(self) -> str: return 'Spotify History Playlist {} on Date {}'.format(self.playlist_id, self.date) class SpotifyWeeklyTopPlaylistTrackHistory(Base): """Spotify track/playlist history. Attributes: playlist_id: Playlist ID. track_id: Track ID. entry_date: Date when its added. exit_date: Date when its removed. """ __tablename__ = 'tblSpotifyWeeklyTopPlaylistTrackHistory' playlist_id = Column('PlaylistId', CHAR(22), primary_key=True) track_id = Column('TrackId', CHAR(22), primary_key=True) entry_date = Column('EntryDate', Date(), primary_key=True) exit_date = Column('ExitDate', Date()) def __str__(self) -> str: return 'Spotify track {} / playlist {} history'.format(self.track_id, self.playlist_id) class SpotifyWeeklyTopPlaylistTrackSummary(Base): """Spotify ISRC/playlist summary for weekly top playlists. Attributes: playlist_id: Playlist ID. isrc: Track ISRC. entry_date: Date when its added. exit_date: Date when its removed. """ __tablename__ = 'tblSpotifyWeeklyTopPlaylistTrackSummary' id = Column('Id', BigInteger, primary_key=True) playlist_id = Column('PlaylistId', CHAR(22)) isrc = Column('ISRC', String(45)) entry_date = Column('EntryDate', Date()) exit_date = Column('ExitDate', Date()) def __str__(self) -> str: return 'Spotify track {} / playlist {} history'.format(self.isrc, self.playlist_id) class SpotifyTrackPlaylistLastWeekHistory(Base): """Set of facts for each of last week dates that track was in playlist. Attributes: date: History date. isrc: Track ISRC. playlist_id: Playlist ID. """ __tablename__ = 'tblSpotifyTrackPlaylistLastWeekHistory' date = Column('Date', Date(), primary_key=True) isrc = Column('ISRC', String(45), primary_key=True) playlist_id = Column('PlaylistId', CHAR(22), primary_key=True) def __str__(self) -> str: return 'Spotify track {} playlist {} history for {}'.format(self.isrc, self.playlist_id, self.date) class SpotifyCustomTopPlaylist(Base): """Spotify custom top playlists. Attributes: playlist_id: Playlist ID. """ __tablename__ = 'tblSpotifyCustomTopPlaylist' playlist_id = Column('PlaylistId', CHAR(22), primary_key=True) def __str__(self) -> str: return 'Spotify custom top playlist {}'.format(self.playlist_id) class SpotifyPlaylistStreamSummary(Base): """Everyday popularity of playlist on market. Primary key combined from playlist_id + market Attributes: playlist_id: Playlist ID. market: Country code. streams_latest: Track ID. listeners_latest: Track order in playlist. latest_date: Date when its added. """ __tablename__ = 'tblSpotifyPlaylistStreamSummary' playlist_id = Column('PlaylistId', CHAR(22), primary_key=True) market = Column('Market', CHAR(2), primary_key=True) streams_7_days = Column('Streams7Days', Integer) streams_latest = Column('StreamsLatest', Integer) listeners_latest = Column('ListenersLatest', Integer) latest_date = Column('LatestDate', TIMESTAMP) def __str__(self) -> str: return 'Spotify Playlist Summary {} on {}'.format(self.playlist_id, self.latest_date) class SpotifyPlaylistStreamSummaryGlobal(Base): """Latest streams and listeners summary for playlists worldwide. Attributes: playlist_id: Playlist ID. streams_latest: Latest day streams. streams_7_days: Latest week streams. streams_14_days: Latest two weeks streams. listeners_latest: Latest day listeners. latest_date: Table row added date. updated: Latest update date. """ __tablename__ = "tblSpotifyPlaylistStreamSummaryGlobal" playlist_id = Column("PlaylistId", CHAR(22), primary_key=True) streams_latest = Column("StreamsLatest", Integer) streams_7_days = Column("Streams7days", Integer) streams_14_days = Column("Streams14days", Integer) listeners_latest = Column("ListenersLatest", Integer) latest_date = Column("LatestDate", TIMESTAMP) updated = Column("Updated", TIMESTAMP) def __str__(self) -> str: return "Spotify playlist streams summary global {}".format(self.playlist_id) class SpotifyPlaylistStream(Base): """Playlists streams per date, country code and distributer ID. Attributes: distributer_id: Distributer ID. date: Stats date. country_code: Country code. playlist_id: Playlist ID. streams: Streams count per day. listeners: Listeners count per day. """ __tablename__ = "tblSpotifyPlaylistStream" distributer_id = Column("DistributerId", Integer, primary_key=True) date = Column("Date", Date, primary_key=True) country_code = Column("CountryCode", String(10), primary_key=True) report_country_code = Column("ReportCountryCode", String(10), primary_key=True) playlist_id = Column("PlaylistUri", String(255), primary_key=True) streams = Column("Streams", Integer) listeners = Column("Listeners", Integer) def __str__(self) -> str: return "Spotify playlist streams {} {} {} {} {}".format( self.distributer_id, self.date, self.country_code, self.report_country_code, self.playlist_id ) class SpotifyPlaylistStreamsWeekHistory(Base): """Playlists week streams per date and country code. Attributes: date: Streams date. playlist_id: Playlist ID. value: Week streams up to record's date. change: Current to previous week streams difference. """ __tablename__ = "tblSpotifyPlaylistStreamsWeekHistory" date = Column("Date", Date, primary_key=True) playlist_id = Column("PlaylistId", CHAR(22), primary_key=True) value = Column("Value", Integer) value_ad = Column("ValueAD", Integer) value_ae = Column("ValueAE", Integer) value_ag = Column("ValueAG", Integer) value_al = Column("ValueAL", Integer) value_am = Column("ValueAM", Integer) value_ao = Column("ValueAO", Integer) value_ar = Column("ValueAR", Integer) value_at = Column("ValueAT", Integer) value_au = Column("ValueAU", Integer) value_az = Column("ValueAZ", Integer) value_ba = Column("ValueBA", Integer) value_bb = Column("ValueBB", Integer) value_bd = Column("ValueBD", Integer) value_be = Column("ValueBE", Integer) value_bf = Column("ValueBF", Integer) value_bg = Column("ValueBG", Integer) value_bh = Column("ValueBH", Integer) value_bi = Column("ValueBI", Integer) value_bj = Column("ValueBJ", Integer) value_bn = Column("ValueBN", Integer) value_bo = Column("ValueBO", Integer) value_br = Column("ValueBR", Integer) value_bs = Column("ValueBS", Integer) value_bt = Column("ValueBT", Integer) value_bw = Column("ValueBW", Integer) value_by = Column("ValueBY", Integer) value_bz = Column("ValueBZ", Integer) value_ca = Column("ValueCA", Integer) value_cd = Column("ValueCD", Integer) value_cg = Column("ValueCG", Integer) value_ch = Column("ValueCH", Integer) value_ci = Column("ValueCI", Integer) value_cl = Column("ValueCL", Integer) value_cm = Column("ValueCM", Integer) value_co = Column("ValueCO", Integer) value_cr = Column("ValueCR", Integer) value_cv = Column("ValueCV", Integer) value_cw = Column("ValueCW", Integer) value_cy = Column("ValueCY", Integer) value_cz = Column("ValueCZ", Integer) value_de = Column("ValueDE", Integer) value_dj = Column("ValueDJ", Integer) value_dk = Column("ValueDK", Integer) value_dm = Column("ValueDM", Integer) value_do = Column("ValueDO", Integer) value_dz = Column("ValueDZ", Integer) value_ec = Column("ValueEC", Integer) value_ee = Column("ValueEE", Integer) value_eg = Column("ValueEG", Integer) value_es = Column("ValueES", Integer) value_et = Column("ValueET", Integer) value_fi = Column("ValueFI", Integer) value_fj = Column("ValueFJ", Integer) value_fm = Column("ValueFM", Integer) value_fr = Column("ValueFR", Integer) value_ga = Column("ValueGA", Integer) value_gb = Column("ValueGB", Integer) value_gd = Column("ValueGD", Integer) value_ge = Column("ValueGE", Integer) value_gh = Column("ValueGH", Integer) value_gm = Column("ValueGM", Integer) value_gn = Column("ValueGN", Integer) value_gq = Column("ValueGQ", Integer) value_gr = Column("ValueGR", Integer) value_gt = Column("ValueGT", Integer) value_gw = Column("ValueGW", Integer) value_gy = Column("ValueGY", Integer) value_hk = Column("ValueHK", Integer) value_hn = Column("ValueHN", Integer) value_hr = Column("ValueHR", Integer) value_ht = Column("ValueHT", Integer) value_hu = Column("ValueHU", Integer) value_id = Column("ValueID", Integer) value_ie = Column("ValueIE", Integer) value_il = Column("ValueIL", Integer) value_in = Column("ValueIN", Integer) value_iq = Column("ValueIQ", Integer) value_is = Column("ValueIS", Integer) value_it = Column("ValueIT", Integer) value_jm = Column("ValueJM", Integer) value_jo = Column("ValueJO", Integer) value_jp = Column("ValueJP", Integer) value_ke = Column("ValueKE", Integer) value_kg = Column("ValueKG", Integer) value_kh = Column("ValueKH", Integer) value_ki = Column("ValueKI", Integer) value_km = Column("ValueKM", Integer) value_kn = Column("ValueKN", Integer) value_kr = Column("ValueKR", Integer) value_kw = Column("ValueKW", Integer) value_kz = Column("ValueKZ", Integer) value_la = Column("ValueLA", Integer) value_lb = Column("ValueLB", Integer) value_lc = Column("ValueLC", Integer) value_li = Column("ValueLI", Integer) value_lk = Column("ValueLK", Integer) value_lr = Column("ValueLR", Integer) value_ls = Column("ValueLS", Integer) value_lt = Column("ValueLT", Integer) value_lu = Column("ValueLU", Integer) value_lv = Column("ValueLV", Integer) value_ly = Column("ValueLY", Integer) value_ma = Column("ValueMA", Integer) value_mc = Column("ValueMC", Integer) value_md = Column("ValueMD", Integer) value_me = Column("ValueME", Integer) value_mg = Column("ValueMG", Integer) value_mh = Column("ValueMH", Integer) value_mk = Column("ValueMK", Integer) value_ml = Column("ValueML", Integer) value_mn = Column("ValueMN", Integer) value_mo = Column("ValueMO", Integer) value_mr = Column("ValueMR", Integer) value_mt = Column("ValueMT", Integer) value_mu = Column("ValueMU", Integer) value_mv = Column("ValueMV", Integer) value_mw = Column("ValueMW", Integer) value_mx = Column("ValueMX", Integer) value_my = Column("ValueMY", Integer) value_mz = Column("ValueMZ", Integer) value_na = Column("ValueNA", Integer) value_ne = Column("ValueNE", Integer) value_ng = Column("ValueNG", Integer) value_ni = Column("ValueNI", Integer) value_nl = Column("ValueNL", Integer) value_no = Column("ValueNO", Integer) value_np = Column("ValueNP", Integer) value_nr = Column("ValueNR", Integer) value_nz = Column("ValueNZ", Integer) value_om = Column("ValueOM", Integer) value_pa = Column("ValuePA", Integer) value_pe = Column("ValuePE", Integer) value_pg = Column("ValuePG", Integer) value_ph = Column("ValuePH", Integer) value_pk = Column("ValuePK", Integer) value_pl = Column("ValuePL", Integer) value_ps = Column("ValuePS", Integer) value_pt = Column("ValuePT", Integer) value_pw = Column("ValuePW", Integer) value_py = Column("ValuePY", Integer) value_qa = Column("ValueQA", Integer) value_ro = Column("ValueRO", Integer) value_rs = Column("ValueRS", Integer) value_ru = Column("ValueRU", Integer) value_rw = Column("ValueRW", Integer) value_sa = Column("ValueSA", Integer) value_sb = Column("ValueSB", Integer) value_sc = Column("ValueSC", Integer) value_se = Column("ValueSE", Integer) value_sg = Column("ValueSG", Integer) value_si = Column("ValueSI", Integer) value_sk = Column("ValueSK", Integer) value_sl = Column("ValueSL", Integer) value_sm = Column("ValueSM", Integer) value_sn = Column("ValueSN", Integer) value_sr = Column("ValueSR", Integer) value_st = Column("ValueST", Integer) value_sv = Column("ValueSV", Integer) value_sz = Column("ValueSZ", Integer) value_td = Column("ValueTD", Integer) value_tg = Column("ValueTG", Integer) value_th = Column("ValueTH", Integer) value_tj = Column("ValueTJ", Integer) value_tl = Column("ValueTL", Integer) value_tn = Column("ValueTN", Integer) value_to = Column("ValueTO", Integer) value_tr = Column("ValueTR", Integer) value_tt = Column("ValueTT", Integer) value_tv = Column("ValueTV", Integer) value_tw = Column("ValueTW", Integer) value_tz = Column("ValueTZ", Integer) value_ua = Column("ValueUA", Integer) value_ug = Column("ValueUG", Integer) value_us = Column("ValueUS", Integer) value_uy = Column("ValueUY", Integer) value_uz = Column("ValueUZ", Integer) value_vc = Column("ValueVC", Integer) value_ve = Column("ValueVE", Integer) value_vn = Column("ValueVN", Integer) value_vu = Column("ValueVU", Integer) value_ws = Column("ValueWS", Integer) value_xk = Column("ValueXK", Integer) value_za = Column("ValueZA", Integer) value_zm = Column("ValueZM", Integer) value_zw = Column("ValueZW", Integer) change = Column("Change", Integer) change_ad = Column("ChangeAD", Integer) change_ae = Column("ChangeAE", Integer) change_ag = Column("ChangeAG", Integer) change_al = Column("ChangeAL", Integer) change_am = Column("ChangeAM", Integer) change_ao = Column("ChangeAO", Integer) change_ar = Column("ChangeAR", Integer) change_at = Column("ChangeAT", Integer) change_au = Column("ChangeAU", Integer) change_az = Column("ChangeAZ", Integer) change_ba = Column("ChangeBA", Integer) change_bb = Column("ChangeBB", Integer) change_bd = Column("ChangeBD", Integer) change_be = Column("ChangeBE", Integer) change_bf = Column("ChangeBF", Integer) change_bg = Column("ChangeBG", Integer) change_bh = Column("ChangeBH", Integer) change_bi = Column("ChangeBI", Integer) change_bj = Column("ChangeBJ", Integer) change_bn = Column("ChangeBN", Integer) change_bo = Column("ChangeBO", Integer) change_br = Column("ChangeBR", Integer) change_bs = Column("ChangeBS", Integer) change_bt = Column("ChangeBT", Integer) change_bw = Column("ChangeBW", Integer) change_by = Column("ChangeBY", Integer) change_bz = Column("ChangeBZ", Integer) change_ca = Column("ChangeCA", Integer) change_cd = Column("ChangeCD", Integer) change_cg = Column("ChangeCG", Integer) change_ch = Column("ChangeCH", Integer) change_ci = Column("ChangeCI", Integer) change_cl = Column("ChangeCL", Integer) change_cm = Column("ChangeCM", Integer) change_co = Column("ChangeCO", Integer) change_cr = Column("ChangeCR", Integer) change_cv = Column("ChangeCV", Integer) change_cw = Column("ChangeCW", Integer) change_cy = Column("ChangeCY", Integer) change_cz = Column("ChangeCZ", Integer) change_de = Column("ChangeDE", Integer) change_dj = Column("ChangeDJ", Integer) change_dk = Column("ChangeDK", Integer) change_dm = Column("ChangeDM", Integer) change_do = Column("ChangeDO", Integer) change_dz = Column("ChangeDZ", Integer) change_ec = Column("ChangeEC", Integer) change_ee = Column("ChangeEE", Integer) change_eg = Column("ChangeEG", Integer) change_es = Column("ChangeES", Integer) change_et = Column("ChangeET", Integer) change_fi = Column("ChangeFI", Integer) change_fj = Column("ChangeFJ", Integer) change_fm = Column("ChangeFM", Integer) change_fr = Column("ChangeFR", Integer) change_ga = Column("ChangeGA", Integer) change_gb = Column("ChangeGB", Integer) change_gd = Column("ChangeGD", Integer) change_ge = Column("ChangeGE", Integer) change_gh = Column("ChangeGH", Integer) change_gm = Column("ChangeGM", Integer) change_gn = Column("ChangeGN", Integer) change_gq = Column("ChangeGQ", Integer) change_gr = Column("ChangeGR", Integer) change_gt = Column("ChangeGT", Integer) change_gw = Column("ChangeGW", Integer) change_gy = Column("ChangeGY", Integer) change_hk = Column("ChangeHK", Integer) change_hn = Column("ChangeHN", Integer) change_hr = Column("ChangeHR", Integer) change_ht = Column("ChangeHT", Integer) change_hu = Column("ChangeHU", Integer) change_id = Column("ChangeID", Integer) change_ie = Column("ChangeIE", Integer) change_il = Column("ChangeIL", Integer) change_in = Column("ChangeIN", Integer) change_iq = Column("ChangeIQ", Integer) change_is = Column("ChangeIS", Integer) change_it = Column("ChangeIT", Integer) change_jm = Column("ChangeJM", Integer) change_jo = Column("ChangeJO", Integer) change_jp = Column("ChangeJP", Integer) change_ke = Column("ChangeKE", Integer) change_kg = Column("ChangeKG", Integer) change_kh = Column("ChangeKH", Integer) change_ki = Column("ChangeKI", Integer) change_km = Column("ChangeKM", Integer) change_kn = Column("ChangeKN", Integer) change_kr = Column("ChangeKR", Integer) change_kw = Column("ChangeKW", Integer) change_kz = Column("ChangeKZ", Integer) change_la = Column("ChangeLA", Integer) change_lb = Column("ChangeLB", Integer) change_lc = Column("ChangeLC", Integer) change_li = Column("ChangeLI", Integer) change_lk = Column("ChangeLK", Integer) change_lr = Column("ChangeLR", Integer) change_ls = Column("ChangeLS", Integer) change_lt = Column("ChangeLT", Integer) change_lu = Column("ChangeLU", Integer) change_lv = Column("ChangeLV", Integer) change_ly = Column("ChangeLY", Integer) change_ma = Column("ChangeMA", Integer) change_mc = Column("ChangeMC", Integer) change_md = Column("ChangeMD", Integer) change_me = Column("ChangeME", Integer) change_mg = Column("ChangeMG", Integer) change_mh = Column("ChangeMH", Integer) change_mk = Column("ChangeMK", Integer) change_ml = Column("ChangeML", Integer) change_mn = Column("ChangeMN", Integer) change_mo = Column("ChangeMO", Integer) change_mr = Column("ChangeMR", Integer) change_mt = Column("ChangeMT", Integer) change_mu = Column("ChangeMU", Integer) change_mv = Column("ChangeMV", Integer) change_mw = Column("ChangeMW", Integer) change_mx = Column("ChangeMX", Integer) change_my = Column("ChangeMY", Integer) change_mz = Column("ChangeMZ", Integer) change_na = Column("ChangeNA", Integer) change_ne = Column("ChangeNE", Integer) change_ng = Column("ChangeNG", Integer) change_ni = Column("ChangeNI", Integer) change_nl = Column("ChangeNL", Integer) change_no = Column("ChangeNO", Integer) change_np = Column("ChangeNP", Integer) change_nr = Column("ChangeNR", Integer) change_nz = Column("ChangeNZ", Integer) change_om = Column("ChangeOM", Integer) change_pa = Column("ChangePA", Integer) change_pe = Column("ChangePE", Integer) change_pg = Column("ChangePG", Integer) change_ph = Column("ChangePH", Integer) change_pk = Column("ChangePK", Integer) change_pl = Column("ChangePL", Integer) change_ps = Column("ChangePS", Integer) change_pt = Column("ChangePT", Integer) change_pw = Column("ChangePW", Integer) change_py = Column("ChangePY", Integer) change_qa = Column("ChangeQA", Integer) change_ro = Column("ChangeRO", Integer) change_rs = Column("ChangeRS", Integer) change_ru = Column("ChangeRU", Integer) change_rw = Column("ChangeRW", Integer) change_sa = Column("ChangeSA", Integer) change_sb = Column("ChangeSB", Integer) change_sc = Column("ChangeSC", Integer) change_se = Column("ChangeSE", Integer) change_sg = Column("ChangeSG", Integer) change_si = Column("ChangeSI", Integer) change_sk = Column("ChangeSK", Integer) change_sl = Column("ChangeSL", Integer) change_sm = Column("ChangeSM", Integer) change_sn = Column("ChangeSN", Integer) change_sr = Column("ChangeSR", Integer) change_st = Column("ChangeST", Integer) change_sv = Column("ChangeSV", Integer) change_sz = Column("ChangeSZ", Integer) change_td = Column("ChangeTD", Integer) change_tg = Column("ChangeTG", Integer) change_th = Column("ChangeTH", Integer) change_tj = Column("ChangeTJ", Integer) change_tl = Column("ChangeTL", Integer) change_tn = Column("ChangeTN", Integer) change_to = Column("ChangeTO", Integer) change_tr = Column("ChangeTR", Integer) change_tt = Column("ChangeTT", Integer) change_tv = Column("ChangeTV", Integer) change_tw = Column("ChangeTW", Integer) change_tz = Column("ChangeTZ", Integer) change_ua = Column("ChangeUA", Integer) change_ug = Column("ChangeUG", Integer) change_us = Column("ChangeUS", Integer) change_uy = Column("ChangeUY", Integer) change_uz = Column("ChangeUZ", Integer) change_vc = Column("ChangeVC", Integer) change_ve = Column("ChangeVE", Integer) change_vn = Column("ChangeVN", Integer) change_vu = Column("ChangeVU", Integer) change_ws = Column("ChangeWS", Integer) change_xk = Column("ChangeXK", Integer) change_za = Column("ChangeZA", Integer) change_zm = Column("ChangeZM", Integer) change_zw = Column("ChangeZW", Integer) def __str__(self) -> str: return "Spotify playlist streams week history {} {}".format(self.date, self.playlist_id) class SpotifyPlaylistDigestStreamsPlaylist(Base): """Playlist digest streams playlists list. Attributes: playlist_id: Playlist ID. category_id: User category ID (like 1 - Sony(Filtr), 5 - Spotify, etc). country_code: Country code. latest_date: Latest available date per playlist. """ __tablename__ = "tblSpotifyPlaylistDigestStreamsPlaylist" playlist_id = Column("PlaylistId", CHAR(22), primary_key=True) category_id = Column("CategoryId", Integer) country_code = Column("CountryCode", String(10)) latest_date = Column("LatestDate", Date) def __str__(self) -> str: return "Spotify Playlist Digest Streams Playlist {}".format(self.playlist_id) class SpotifyWeeklyTopPlaylist(Base): """Weekly popularity of playlist. Attributes: date: Report date. country: Country code. rank: Playlist rank, ordered from 1 playlist_name: Human readable playlist name playlist_uri: String with spotify user name and playlist ID """ __tablename__ = 'tblSpotifyWeeklyTopPlaylist' date = Column('Date', Date(), primary_key=True) country = Column('Country', String(255), primary_key=True) rank = Column('Rank', Integer, primary_key=True) playlist_name = Column('PlaylistName', String(1024), nullable=False) playlist_uri = Column('PlaylistUri', String(1024), nullable=False) playlist_id = Column('PlaylistId', String(255), nullable=False) def __str__(self) -> str: return 'Spotify Weekly {} on {}'.format(self.playlist_name, self.date) class SpotifyWeeklyTopPlaylistLatest(Base): """The latest weekly top playlists. Attributes: id: Table ID, primary key. playlist_id: Playlist ID. date: Report date. country_code: Country code. rank: Playlist rank. """ __tablename__ = "tblSpotifyWeeklyTopPlaylistLatest" id = Column("Id", Integer, primary_key=True) playlist_id = Column("PlaylistId", String(45), nullable=False) date = Column("Date", Date, nullable=False) country_code = Column("CountryCode", String(10), nullable=False) rank = Column("Rank", Integer, nullable=False) def __str__(self) -> str: return f"Spotify Weekly Top Playlist {self.country_code} {self.playlist_id}" class SpotifyPersonalizedPlaylist(Base): """Personalized playlist IDs. Attributes playlist_id (str): Personalized playlist ID. """ __tablename__ = 'tblSpotifyPersonalizedPlaylist' playlist_id = Column('PlaylistId', String(22), primary_key=True) def __str__(self) -> str: return f'Spotify personalized playlist {self.playlist_id}' class SpotifyAnalyticsAccountStreamInfo(Base): """Spotify Analytics Account Stream Info. Attributes: account: Account ID. market: Market of chart. date: Report date. total_streams: Total streams. """ __tablename__ = 'tblSpotifyAnalyticsAccountStreamInfo' account = Column('AccountId', SmallInteger, primary_key=True) market = Column('Market', String(10), primary_key=True) date = Column('Date', Date, primary_key=True) total_streams = Column('TotalStreams', Integer) def __str__(self) -> str: return 'Spotify Analytics {} - {} streams'.format(self.market, self.total_streams) class SpotifyTrackStreamDemographics(Base): """Spotify Track Streams Data by gender and age range.""" __tablename__ = 'tblSpotifyTrackStreamDemographics' distributor_id = Column('DistributerId', Integer, primary_key=True) date = Column('Date', Date, primary_key=True) country_code = Column('CountryCode', String(10), primary_key=True) isrc = Column('Isrc', String(45), primary_key=True) report_date = Column('ReportDate', Date) report_country_code = Column('ReportCountryCode', String(10)) female_0_17 = Column('GenderFemaleAge_0_17', Integer) male_0_17 = Column('GenderMaleAge_0_17', Integer) neutral_0_17 = Column('GenderNeutralAge_0_17', Integer) unknown_0_17 = Column('GenderUnknownAge_0_17', Integer) female_18_22 = Column('GenderFemaleAge_18_22', Integer) male_18_22 = Column('GenderMaleAge_18_22', Integer) neutral_18_22 = Column('GenderNeutralAge_18_22', Integer) unknown_18_22 = Column('GenderUnknownAge_18_22', Integer) female_23_27 = Column('GenderFemaleAge_23_27', Integer) male_23_27 = Column('GenderMaleAge_23_27', Integer) neutral_23_27 = Column('GenderNeutralAge_23_27', Integer) unknown_23_27 = Column('GenderUnknownAge_23_27', Integer) female_28_34 = Column('GenderFemaleAge_28_34', Integer) male_28_34 = Column('GenderMaleAge_28_34', Integer) neutral_28_34 = Column('GenderNeutralAge_28_34', Integer) unknown_28_34 = Column('GenderUnknownAge_28_34', Integer) female_35_44 = Column('GenderFemaleAge_35_44', Integer) male_35_44 = Column('GenderMaleAge_35_44', Integer) neutral_35_44 = Column('GenderNeutralAge_35_44', Integer) unknown_35_44 = Column('GenderUnknownAge_35_44', Integer) female_45_59 = Column('GenderFemaleAge_45_59', Integer) male_45_59 = Column('GenderMaleAge_45_59', Integer) neutral_45_59 = Column('GenderNeutralAge_45_59', Integer) unknown_45_59 = Column('GenderUnknownAge_45_59', Integer) female_60_150 = Column('GenderFemaleAge_60_150', Integer) male_60_150 = Column('GenderMaleAge_60_150', Integer) neutral_60_150 = Column('GenderNeutralAge_60_150', Integer) unknown_60_150 = Column('GenderUnknownAge_60_150', Integer) female_unknown = Column('GenderFemaleAge_unknown', Integer) male_unknown = Column('GenderMaleAge_unknown', Integer) neutral_unknown = Column('GenderNeutralAge_unknown', Integer) unknown_unknown = Column('GenderUnknownAge_unknown', Integer) def __str__(self) -> str: return 'Spotify Track {} - {} streams demographic'.format(self.isrc, self.date) class SpotifyHotHitsPlaylistTrackSummary(Base): """Spotify tracks (ISRC) to hot hits playlists entries date ranges. Attributes: id: Primary key. isrc: Track ISRC. playlist_id: Spotify playlist ID. entry_date: Track in playlist entry date. exit_date: Track from playlist exit date. """ __tablename__ = 'tblSpotifyHotHitsPlaylistTrackSummary' id = Column('Id', BigInteger, primary_key=True) isrc = Column('ISRC', String(15), nullable=False) playlist_id = Column('PlaylistId', String(22), nullable=False) entry_date = Column('EntryDate', Date, nullable=False) exit_date = Column('ExitDate', Date, nullable=False) def __str__(self) -> str: return 'Spotify Hot Hits Playlist Track entry {}'.format(self.id) class SpotifyHotHitsPlaylistTrackStats(Base): """Spotify tracks (ISRC) in hot hits playlists metrics. Attributes: id: Primary key. isrc: Track ISRC. playlist_id: Spotify playlist ID. entry_date: Track into playlist entry date. latest_date: Exit or latest date. latest_position: Latest track position in playlist (exit position or current). previous_date: Previous position date to latest. previous_position: Previous position to latest. peak_position: Top position. peak_date: First top position date. """ __tablename__ = "tblSpotifyHotHitsPlaylistTrackStats" id = Column("Id", BigInteger, primary_key=True) isrc = Column("ISRC", String(15), nullable=False) playlist_id = Column("PlaylistId", String(22), nullable=False) entry_date = Column("EntryDate", Date, nullable=False) latest_date = Column("LatestDate", Date, nullable=False) latest_position = Column("LatestPosition", Integer, nullable=False) previous_date = Column("PreviousDate", Date, nullable=True) previous_position = Column("PreviousPosition", Integer, nullable=True) peak_position = Column("PeakPosition", Integer, nullable=False) peak_date = Column("PeakDate", Date, nullable=False) added_date = Column("AddedDate", Date, nullable=True) in_history = Column("InHistory", Boolean, nullable=False) @property def latest_is_entry(self): return self.latest_date == self.entry_date @property def latest_trend(self): return ( None if self.previous_position is None or self.latest_position == self.previous_position else self.latest_position - self.previous_position ) def __str__(self) -> str: return "Spotify Hot Hits Playlist Track stats {}".format(self.id) class SpotifyPlaylistFollowers(Base): """Spotify playlists followers collection. Attributes: playlist_uri: Playlist URI (primary key). playlist_id: Playlist ID. followers: Current followers count. followers_1_day: Followers count 1 day ago. followers_7_day: Followers count 7 day ago. followers_14_day: Followers count 14 day ago. followers_28_day: Followers count 28 day ago. followers_56_day: Followers count 56 day ago. update_date: Update date. """ __tablename__ = "tblSpotifyPlaylistFollowers" playlist_uri = Column("PlaylistUri", String(100), primary_key=True) playlist_id = Column("PlaylistId", String(22)) followers = Column("Followers", Integer) followers_1_day = Column("Followers1dayAgo", Integer) followers_7_days = Column("Followers7daysAgo", Integer) followers_14_days = Column("Followers14daysAgo", Integer) followers_28_days = Column("Followers28daysAgo", Integer) followers_56_days = Column("Followers56daysAgo", Integer) update_date = Column("UpdateDate", Date) def __str__(self) -> str: return "Spotify playlists followers {}".format(self.playlist_uri) class SpotifyPlaylistFollowersHistory(Base): """Spotify playlist followers history model. Attributes: playlist_id: Playlist ID. followers: Date followers count. date: Date. timestamp: Update timestamp. """ __tablename__ = "tblSpotifyPlaylistFollowerHistory" playlist_id = Column("PlaylistId", String(22), primary_key=True) date = Column("Date", Date, primary_key=True) followers = Column("Followers", Integer) timestamp = Column("Timestamp", TIMESTAMP) def __str__(self) -> str: return "Spotify playlist followers {} for {}".format(self.playlist_id, self.date) class SpotifyPlaylistFollowersWeekHistory(Base): """Spotify playlist week followers history. Attributes: date: Date. playlist_id: Playlist ID. value: Week followers up to record's date. change: Current to previous week followers difference. """ __tablename__ = "tblSpotifyPlaylistFollowersWeekHistory" date = Column("Date", Date, primary_key=True) playlist_id = Column("PlaylistId", String(22), primary_key=True) value = Column("Value", Integer) change = Column("Change", Integer) def __str__(self) -> str: return "Spotify playlist followers week history {} {}".format(self.date, self.playlist_id) class SpotifyPlaylistDigestFollowersPlaylist(Base): """Playlist digest followers playlists list. Attributes: playlist_id: Playlist ID. category_id: User category ID (1 - Sony(Filtr), 5 - Spotify, etc). country_code: Country code. latest_date: Latest available date per playlist. """ __tablename__ = "tblSpotifyPlaylistDigestFollowersPlaylist" playlist_id = Column("PlaylistId", CHAR(22), primary_key=True) category_id = Column("CategoryId", Integer) country_code = Column("CountryCode", String(10)) latest_date = Column("LatestDate", Date) def __str__(self) -> str: return "Spotify Playlist Digest Followers Playlist {}".format(self.playlist_id) class SpotifyNewMusicFridayDate(Base): """Spotify NMF dates collection. Attributes: id: ID. date: NMF Date. """ __tablename__ = "tblSpotifyNewMusicFridayDate" id = Column("Id", Integer, primary_key=True) date = Column("Date", Date, nullable=False) def __str__(self) -> str: return "Spotify NMF date {}".format(self.date) class SpotifyNewMusicFridayPlaylistTrackHistory(Base): """Spotify NMF playlists tracks per date collection. Attributes: date_id: NMF Date ID. playlist_id: Playlist ID. playlist_index: Track position in playlist. track_id: Track ID. added: Timestamp of adding to playlist. isrc: Track ISRC. """ __tablename__ = "tblSpotifyNewMusicFridayPlaylistTrackHistory" date_id = Column("DateId", Integer, primary_key=True) playlist_id = Column("PlaylistId", String(22), primary_key=True) playlist_index = Column("PlaylistIndex", Integer, primary_key=True) track_id = Column("TrackId", String(22), nullable=False) added = Column("Added", DateTime) isrc = Column("ISRC", String(15)) def __str__(self) -> str: return "Spotify NMF playlist track {} {} {}".format(self.date_id, self.playlist_id, self.playlist_index) class SpotifyAlbum(Base): """Spotify Album. Attributes: id: Album ID. name: Album name. type: Album type. popularity: Popularity. copyright: Copyright. label: Label. upc: UPC. release_date: Release date. release_date_precision: Release date precision. small_image_filename: Small image filename. updated: Updated timestamp. """ __tablename__ = "tblSpotifyAlbum" id = Column("AlbumId", String(255), primary_key=True) name = Column("Name", String(1000)) type = Column("AlbumType", String(45)) popularity = Column("Popularity", Integer) copyright = Column("Copyright", String(1000)) label = Column("Label", String(100)) upc = Column("Upc", String(100)) release_date = Column("ReleaseDate", String(20)) release_date_precision = Column("ReleaseDatePrecision", Integer) small_image_filename = Column("SmallImageFilename", String(45)) updated = Column("Updated", TIMESTAMP) def __str__(self) -> str: return "Spotify Album {}".format(self.id) class SpotifyPlaylistLegacyUri(Base): """Spotify playlists legacy uri map model. Attributes: playlist_id: Current Playlist ID value. playlist_uri: Legacy Playlist URI value. """ __tablename__ = "tblSpotifyPlaylistLegacyUri" playlist_id = Column("PlaylistId", String(22), primary_key=True) playlist_uri = Column("PlaylistUri", String(255)) def __str__(self): return f"Legacy URI for playlist {self.playlist_id}" class SpotifyAnalyticsPlaylistStreamInfo(Base): """Spotify Playlists Analytics Account Stream Info. Attributes: account: Account ID. market: Market of chart. playlist_uri: Playlist identifier. date: Report date. total_streams: Total streams. listeners: Listeners value. """ __tablename__ = "tblSpotifyAnalyticsAccountPlaylistStreamInfo" account = Column('AccountId', SmallInteger, primary_key=True) playlist_uri = Column('PlaylistUri', String(100), primary_key=True) market = Column('Market', String(10), primary_key=True) date = Column('Date', Date, primary_key=True) total_streams = Column('TotalStreams', Integer) listeners = Column("UniqueUsers", Integer) def __str__(self) -> str: return f'Spotify Playlists Analytics {self.playlist_uri} - {self.market}' class SpotifyPlaylistStatistics(Base): """Spotify Playlist Statistics model. Keeps information about playlists tracklist update. Attributes: playlist_id: Playlist identifier. market: Market of playlist. tracklist_updated_at: Playlists tracklist update datetime. """ __tablename__ = "tblSpotifyPlaylistStatistics" id = Column('Id', Integer, primary_key=True) playlist_id = Column('PlaylistId', CHAR(22)) market = Column('Market', CHAR(10)) tracklist_updated_at = Column('TracklistLastUpdate', DateTime) def __str__(self) -> str: return f'Spotify Playlists Statistics {self.playlist_id} - {self.market} - {self.tracklist_updated_at}' class SpotifyViewPlaylist(Base): """Spotify specific view playlists. Attributes: type: Type code. playlist_id: Playlist ID. market_code: Market code. category_id: GTP category (type) ID. last_date: Last updated date. last_added_ts: Last track added timestamp for NMF. """ __tablename__ = "tblSpotifyViewPlaylist" type = Column("Type", Enum(ViewPlaylistTypeEnum), nullable=False, primary_key=True) playlist_id = Column("PlaylistId", CHAR(22), nullable=False, primary_key=True) market_code = Column("MarketCode", String(10), ForeignKey("tblApolloMarket.Code"), nullable=True) category_id = Column("CategoryId", Integer, nullable=True) last_date = Column("LastDate", Date, nullable=True) last_added_ts = Column("LastAddedTs", DateTime, nullable=True) market = relationship("ApolloMarket") def __str__(self) -> str: return f"View Playlist {self.type.name} {self.playlist_id} {self.market_code} {self.last_date}" class SpotifyMarketRank(Base): """Type and market code mapping to rank. Attributes: type: Type code. market_code: Market code. rank: Market rank. """ __tablename__ = "tblSpotifyMarketRank" type = Column("Type", Enum(MarketRankTypeEnum), nullable=False, primary_key=True) market_code = Column("MarketCode", String(10), ForeignKey("tblApolloMarket.Code"), nullable=False, primary_key=True) rank = Column("Rank", Integer, nullable=False) market = relationship("ApolloMarket") def __str__(self) -> str: return f"Market Rank {self.type.name} {self.market_code} {self.rank}" class SpotifyPlaylistDigestPlaylist(Base): """Playlist digest playlists. Attributes: playlist_id: Playlist ID. category_id: User category ID (1 - Sony(Filtr), 5 - Spotify, etc). country_code: Country code. is_personalized: Is personalized playlist or not. """ __tablename__ = "tblSpotifyPlaylistDigestPlaylist" playlist_id = Column("PlaylistId", CHAR(22), primary_key=True) category_id = Column("CategoryId", Integer) country_code = Column("CountryCode", String(10)) is_personalized = Column("IsPersonalized", Boolean) def __str__(self) -> str: return "Spotify Playlist Digest Playlist {}".format(self.playlist_id)