"""Utils for manipulating data.""" from collections import OrderedDict from bulk_metadata_ingester_common.constants import spreadsheet as tab_consts from bulk_metadata_ingester_common.constants.data_headers import FIELD_JOIN_CONST # noqa: E501 from bulk_metadata_ingester_common.exceptions import ChunkException import pandas as pd def pivot_bulk_file(bulk_upload_rows, logger): """Collate file rows into groups of project/product keys. Args: bulk_upload_rows (pandas.DataFrame): The CSV data as a DataFrame. logger (Logger) Returns: dict: A collated dict of lists of tracks """ # Init vars project_code = None product_code = None data_by_release = OrderedDict() product_data_list = list() # the list of tracks for a project row_number = 2 # Excel spreadsheets start at row 2 total_rows = 0 release_count = 0 # Syntactic Sugar - Shorten constants PROJ_CONST = tab_consts.folder_name_project_code PROD_CONST = tab_consts.product_code # Get a list of unique keys package_list = list( dict.fromkeys( [f'{r[PROJ_CONST]}{FIELD_JOIN_CONST}{r[PROD_CONST]}' for _, r in bulk_upload_rows.iterrows()] ) ) # Get the count count_of_packages = len(package_list) # Iterate over DB result rows for i, row in bulk_upload_rows.iterrows(): # each row (multiple projects) total_rows += 1 # Checks for initial app state if not project_code: project_code = row.get(PROJ_CONST) if not product_code: product_code = row.get(PROD_CONST) # Check for change in product_code values if (product_code != row.get(PROD_CONST)) or \ (project_code != row.get(PROJ_CONST)): # Store finished product data_by_release[f'{project_code}{FIELD_JOIN_CONST}{product_code}']\ = pd.DataFrame(product_data_list).to_dict(orient='records') # Bump release count release_count += 1 # Debug logger.info( f'Release {project_code}{FIELD_JOIN_CONST}{product_code} ' f'prepared.') # Reset product dict product_data_list = list() # Update project and product codes product_code = row[PROD_CONST] project_code = row[PROJ_CONST] # Add row number field row[tab_consts.catalog_ingest_order] = row_number row_number += 1 # Append product to project product_data_list.append(row.copy()) # Shorten the key release_key = f'{project_code}{FIELD_JOIN_CONST}{product_code}' # Append final product to list if product_data_list: data_by_release[release_key] = \ pd.DataFrame(product_data_list).to_dict(orient='records') logger.info(f'Release {release_count} prepared.') # Check the processed count matches the expected amount if len(data_by_release) != count_of_packages: # TODO: Throw Exception instead of die raise ChunkException('Something did not get chunked properly.') return data_by_release