"""Snowflake connector class for TikTok Statistics tasks.""" import csv import datetime from snowflake_connector.etl_connector import SQLLoader from snowflake_connector.etl_connector import SnowflakeSQLExecutor import config # Load SQL templates sql_loader = SQLLoader(__file__) looker_sql_loader = SQLLoader(__file__, folder='/looker_queries') class TikTokStatsSFExecutor(SnowflakeSQLExecutor): """Helper class to abstract Snowflake operations.""" @property def artist_to_track_table(self): """Name of the artist_to_track table for the statistics. Returns: str: {stats}_artist_to_track table name. """ return config.snowflake_table_names['artist_to_track'] @property def tiktok_statistics_table(self): """Name of the artist_to_track table for the statistics. Returns: str: {stats}_artist_to_track table name. """ return config.snowflake_table_names['tiktok_statistics'] @property def staging_raw_table(self): """Name of the staging raw table for the statistics. Returns: str: staging raw table name. """ return config.snowflake_table_names['staging_raw'] def create_tiktok_statistics(self): """Create tiktok statistics historical table.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.tiktok_statistics_table) return self.fetchone_query(sql_loader, 'create_tiktok_statistics', params) def create_staging_raw_tiktok_statistics(self): """Create staging raw tiktok statistics historical table.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.staging_raw_table) return self.fetchone_query(sql_loader, 'create_tiktok_statistics', params) def select_artists_links(self): """Selecting artists links from artist_to_track.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.artist_to_track_table) result = self.fetchall_query(sql_loader, 'select_artists', params) return result def select_artists_stats(self): """Select all stats.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.tiktok_statistics_table) result = self.fetchall_query(sql_loader, 'select_artists_stats', params) return result def select_artist_stats(self, artist): """Select stats for certain artist.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.tiktok_statistics_table, artist=artist) result = self.fetchall_query(sql_loader, 'select_artist_stats', params) return result def update_artist_stats(self, artist: str, stats: dict): """Load main statistics table.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.tiktok_statistics_table, artist=artist, tiktok_link=stats.get('link'), current_followers=stats.get('current_followers'), weekly_change_in_followers=stats.get('weekly_change_in_followers'), daily_change_in_followers=stats.get('daily_change_in_followers'), current_weekly_change_in_followers=stats.get('current_weekly_change_in_followers'), last_week_followers=stats.get('last_week_followers'), percentage_change_in_followers=stats.get('percentage_change_in_followers'), current_followings=stats.get('current_followings'), weekly_change_in_followings=stats.get('weekly_change_in_followings'), daily_change_in_followings=stats.get('daily_change_in_followings'), current_weekly_change_in_followings=stats.get('current_weekly_change_in_followings'), last_week_followings=stats.get('last_week_followings'), percentage_change_in_followings=stats.get('percentage_change_in_followings'), current_likes=stats.get('current_likes'), weekly_change_in_likes=stats.get('weekly_change_in_likes'), daily_change_in_likes=stats.get('daily_change_in_likes'), current_weekly_change_in_likes=stats.get('current_weekly_change_in_likes'), last_week_likes=stats.get('last_week_likes'), percentage_change_in_likes=stats.get('percentage_change_in_likes'), last_processing_date=stats.get('last_processing_date'), last_week_processing_date=stats.get('last_week_processing_date'), ) result = self.fetchall_query(sql_loader, 'update_artists_stats', params) return result def update_artist_stats_last_processing_date(self, artist: str, last_processing_date: datetime): """Update artists statistics table on failure.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.tiktok_statistics_table, last_processing_date=last_processing_date.strftime("%d-%m-%Y"), artist=artist ) result = self.fetchall_query(sql_loader, 'update_artists_stats_last_processing_date', params) return result def update_stating_raw_tiktok_stats(self): """Load staging raw table.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.tiktok_statistics_table, staging_raw_table_name=self.staging_raw_table ) result = self.fetchall_query(sql_loader, 'update_stating_raw_tiktok_stats', params) return result def select_weekly_change(self, artist, first_day_of_period=0, last_day_of_period=-7): """Select artist weekly change in metrics from staging raw table.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.staging_raw_table, artist=artist, first_day_of_period=first_day_of_period, last_day_of_period=last_day_of_period ) result = self.fetchall_query(sql_loader, 'select_weekly_change', params) try: weeklies = result[0] if len(result[0]) == 3 else [0] * 3 except IndexError: weeklies = [0] * 3 return dict(zip(['followers', 'followings', 'likes'], list(weeklies))) def delete_from_staging_raw(self): """Delete from staging raw today's rows to prevent duplicates.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], staging_raw_table=self.staging_raw_table, date=datetime.datetime.today().strftime("%Y-%m-%d")) result = self.fetchall_query(sql_loader, 'delete_from_staging_raw', params) return result def insert_artist_stats(self, artist, stats): """First TikTok statistics insertion.""" params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], table_name=self.tiktok_statistics_table, artist=artist, tiktok_link=stats.get('link'), current_followers=stats.get('current_followers'), weekly_change_in_followers=stats.get('weekly_change_in_followers'), daily_change_in_followers=stats.get('daily_change_in_followers'), current_weekly_change_in_followers=stats.get('current_weekly_change_in_followers'), last_week_followers=stats.get('last_week_followers'), percentage_change_in_followers=stats.get('percentage_change_in_followers'), current_followings=stats.get('current_followings'), weekly_change_in_followings=stats.get('weekly_change_in_followings'), daily_change_in_followings=stats.get('daily_change_in_followings'), current_weekly_change_in_followings=stats.get('current_weekly_change_in_followings'), last_week_followings=stats.get('last_week_followings'), percentage_change_in_followings=stats.get('percentage_change_in_followings'), current_likes=stats.get('current_likes'), weekly_change_in_likes=stats.get('weekly_change_in_likes'), daily_change_in_likes=stats.get('daily_change_in_likes'), current_weekly_change_in_likes=stats.get('current_weekly_change_in_likes'), last_week_likes=stats.get('last_week_likes'), percentage_change_in_likes=stats.get('percentage_change_in_likes'), last_processing_date=stats.get('last_processing_date'), last_week_processing_date=stats.get('last_week_processing_date'), ) result = self.fetchall_query(sql_loader, 'insert_artists_stats', params) return result