"""The Snowflake connector class for the common marketshare tasks.""" from snowflake_connector.etl_connector import SQLLoader from feed_ingestion.common.fact_analytics_sf.base_executor \ import SnowflakeAWSExecutor # Load SQL templates sql_loader = SQLLoader(__file__) class SnowflakeSQLExecutorMS(SnowflakeAWSExecutor): """Helper class to abstract loading of marketshare tables. 'MS' in 'SnowflakeSQLExecutorMS' stands for 'marketshare'. This class inherits from SnowflakeSQLExecutor class, which provides basic set of methods. This class extends SnowflakeSQLExecutor with some specific methods, which are useful to encapsulate market share loading methods. """ @property def feed_name(self): """Name of the feed. Should match dir name of this feed, feed_name in config.py of a feed, and a key of executors dict in feed_ingestion/common/__init__.py file. Returns: str: Feed name, e.g. 'deezer_daily_sf'. """ raise NotImplementedError() @property def storeid(self): """Storeid of feed data. Should match dim_store and feed config value. Returns: integer: Feed's storeid. """ raise NotImplementedError() @property def staging_raw_table(self): """Name of the staging_raw table for the feed. Returns: str: staging_raw_{feed} table name. """ raise NotImplementedError() @property def main_marketshare_table(self): """Name of the marketshare table for feed. 'fact_market_share' for all feeds. Optional name may be used for testing purposes. Returns: str: Marketshare table name. """ return 'fact_market_share' def _delete_from_marketshare_table(self, table, date): """Delete rows in main marketshare table with the current run date. This is required for the workflow to be idempotent, and to avoid row duplication. Before we'll load rows for a specific day to main_marketshare, we have to delete rows which were added by previous (allegedly unsuccessful workflow run). Args: table (str): 'fact_market_share'. date (str): Date of the data being process (YYYY-MM-DD). """ sql_template = sql_loader.load_query( 'delete_from_main_market_share_table') params = dict( db=self.sf_config['db'], schema=self.sf_config['schema'], main_market_share_table=table, storeid=self.storeid, date=date) sql_template, non_identifier_params = ( self.validator.format_identifiers(sql_template, params)) return self.fetchone(sql_template, params=non_identifier_params)[0] def delete_from_marketshare_table(self, date): """Delete rows in main_market_share table with the current run date. Args: date (str): Date of the data being process (YYYY-MM-DD). """ self._delete_from_marketshare_table( self.main_marketshare_table, date) def load_marketshare_data(self, date): """Load data into main_market_share. Args: date (str): Date of the data being process (YYYY-MM-DD). """ raise NotImplementedError()