from config import config import os # from contribution_backfill import backfill, backfillOne from queries import queries from connection import mysql, snowflake from stores import stores import sentry_sdk log = config.get_logger() sentry_sdk.init(config.SENTRY_DSN) BATCH_SIZE = 200 CONTRIBUTION_BATCH_SIZE = 500 def connect(): cmm_id = os.environ.get("CMM_ID") queue = os.environ.get("QUEUE", False) offset = 0 limit = 1000 if not cmm_id: raise Exception("no CMM_ID env var set") # first we need a society store = stores.get_store_by_cmm_id(int(cmm_id)) try: if queue == "True": run_queue_for_store(store) else: log.info(f"history - importing for society {cmm_id}") order_id = mysql.create_order(cmm_id) log.info(f"history - {cmm_id} - order {order_id} created") cs = snowflake.get_cursor() contributors = queries.all_types_of_contributor_for_society( cs, store["IP"], offset, limit ) while len(contributors) > 0: for contributor in contributors: job_id = 0 css = snowflake.get_cursor(target="contributions") contributionOffset = 0 contributionLimit = 1000 contributor_uuid = contributor["NEO_CONTRIBUTOR_UUID"] # FIND CONTRIBUTIONS contributions = queries.by_society_and_contributor_all( css, store["IP"], contributor_uuid, False, contributionOffset, contributionLimit, ) # INSERT CONTRIBUTIONS if len(contributions) > 0 and job_id == 0: log.info(f"history - {cmm_id} - contributor {contributor_uuid}") # insert into the jobs table and obtain the primary key for the newly created row (batch this?) # but do not do this until we know this contributor has some 'butions job_id = mysql.insert_contributor_society_into_jobs_table( order_id, contributor_uuid ) while len(contributions) > 0: contribution_counter = 0 for contribution in contributions: contribution_counter += 1 if contribution_counter % 100 == 0: log.info( f"history - {cmm_id} - latest uuid {contribution['CONTRIBUTION_UUID']}" ) status_id = contribution["STATUS_ID"] status = queries.status[status_id] created_date = contribution["CREATED_DATE"] claim_id = mysql.insert_job_contribution_into_claims_table( job_id, contribution["CONTRIBUTION_UUID"], status, created_date, ) mysql.commit() contributionOffset += contributionLimit css = snowflake.get_cursor(target="contributions") contributions = queries.by_society_and_contributor_all( css, store["IP"], contributor_uuid, False, contributionOffset, contributionLimit, ) cs = snowflake.get_cursor() offset += limit contributors = queries.all_types_of_contributor_for_society( cs, store["IP"], offset, limit ) except Exception as err: log.error(err) if config.SENTRY_DSN: sentry_sdk.capture_exception(err) finally: snowflake.close() mysql.close() if queue == "True": log.info(f"finished queue for {cmm_id}") else: log.info(f"finished history for {cmm_id}") def run_queue_for_store(store): queue = True if not store: raise Exception("no store to queue") cmm = store["CMO"] log.info(f"queue - for society {cmm}") store_ip = store["IP"] offset = 0 limit = 1000 try: cs = snowflake.get_cursor() contributors = queries.all_types_of_contributor_for_society( cs, store_ip, offset, limit ) while len(contributors) > 0: for contributor in contributors: contributor_uuid = contributor["NEO_CONTRIBUTOR_UUID"] log.info(f"queue - {cmm} - contributor {contributor_uuid}") contributionOffset = 0 contributionLimit = 1000 # FIND CONTRIBUTIONS css = snowflake.get_cursor(target="contributions") contributions = queries.by_society_and_contributor_all( css, store_ip, contributor_uuid, queue, contributionOffset, contributionLimit, ) counter = 0 values_to_insert = "" while len(contributions) > 0: for contribution in contributions: s_id = store["CMO"] c_uuid = contribution["CONTRIBUTION_UUID"] if not c_uuid: log.error(f"no contribution uuid for {contribution}") continue counter += 1 if counter % 100 == 0: log.info(f"queue - {cmm} - contribution {c_uuid}") values_to_insert += ( f"('{c_uuid}', {s_id}, '{contributor_uuid}')," ) values_to_insert = values_to_insert[:-1] + ";" mysql.add_many_to_queue(values_to_insert) values_to_insert = "" css = snowflake.get_cursor(target="contributions") contributionOffset += contributionLimit contributions = queries.by_society_and_contributor_all( css, store_ip, contributor_uuid, queue, contributionOffset, contributionLimit, ) cs = snowflake.get_cursor() offset += limit contributors = queries.all_types_of_contributor_for_society( cs, store_ip, offset, limit ) except Exception as e: log.error(e) raise e def remove_excluded(): try: # Fetch all excluded contributions from claims table which also exist in the delivery_queue table excluded_contributions = mysql.fetch_excluded_contributions() log.info(f"fetched {excluded_contributions[1]} contributions") contribution_counter = 0 for contribution in excluded_contributions[0]: # For each excluded contribution, find if a new claim exists (i.e. same contributionUuid and same storeId) result, row_count = mysql.fetch_claims_for_contribution_cmo(contribution[0], contribution[1]) contribution_counter += 1 if contribution_counter % 100 == 0: log.info(f"contributionId: {result[0][0]}, cmoId: {result[0][1]}, #claims: {row_count}, counter: {contribution_counter}") # If new claim exists and status = excluded, delete contributions from queue. # If new claim exists and status != excluded, leave it in the queue. if row_count > 1: latest_contribution = result[0] status = latest_contribution[3] if (status == 'excluded'): deleted_contribution = mysql.delete_excluded_contributions_from_queue(latest_contribution[0], latest_contribution[1]) if deleted_contribution > 0: log.info(f"delete from queue where contributionId: {latest_contribution[0]} and cmoId: {latest_contribution[1]}") # If no new claim exists, delete the contribution from the queue. elif row_count == 1: deleted_contribution = mysql.delete_excluded_contributions_from_queue(result[0][0], result[0][1]) if deleted_contribution > 0: log.info(f"delete from queue where contributionId: {result[0][0]} and cmoId: {result[0][1]}") except Exception as err: log.error(err) finally: mysql.close() if __name__ == "__main__": # connect() # uncomment for the s3 backfill # runOnce = os.environ.get("QUEUE", False) # if runOnce == "True": # backfillOne(log) # else: # backfill(log) remove_excluded()