from sqlalchemy import update from bulkperformancerights.connectors import mysql from bulkperformancerights.models import country from bulkperformancerights.models.track import Track from bulkperformancerights.models.track_master_rights import TrackMasterRights from bulkperformancerights.models.track_producer_nationality import \ TrackProducerNationality from bulkperformancerights.models.track_writer import TrackWriter def update_track_recording_country(session, track_id, recording_country_id): """"Update track recording country Args: session(Session): sqlalchemy session connected to art_relations track_id(int): id of track to update recording_country_id(int): country_id where the recording happened Return: (ResultProxy): result of the update operation """ update_stmt = update(Track).where(Track.id == track_id).values( recording_country=recording_country_id) result = session.execute(update_stmt) session.commit() return result def update_track_writer(session, track_id, writer_names): """"Update track_writers by performing a delete and inserts Args: session(Session): sqlalchemy session connected to art_relations track_id(int): id of track to update writer_names(list): list of track writer names Return: (ResultProxy): result of the insert operations """ # Todo (OrCharles): remove the ORM from the delete, just use DBAL/SQL existing_track_writers = session.query(TrackWriter).filter_by( unique_track_id=track_id) for existing_track_writer in existing_track_writers: session.delete(existing_track_writer) track_writer_list = [] for writer_name in writer_names: # construct dict for insert statement track_writer_list.append(dict(unique_track_id=track_id, writer_name=writer_name)) insert_result = session.execute(TrackWriter.__table__.insert(). values(track_writer_list)) session.commit() return insert_result def update_master_rights_ownership(session, track_id, is_owner): """ Update or insert track master rights ownership Since this is not a required field on tracks and sqlalchemy doesn't provide 'on duplicate key update' functionality we are doing this the slightly more expensive way until/unless it becomes problematic Args: session(Session): sqlalchemy session connected to art_relations track_id(int): id of track to update is_owner(str): 'Yes' or 'No' Returns: (ResultProxy): result of the update or insert operation """ yes_no_enum_dict = {'Yes': 'y', 'No': 'n'} yes_no_enum_val = yes_no_enum_dict[is_owner] track_master_rights_exists = session.query(TrackMasterRights)\ .filter_by(track_id=track_id).first() if track_master_rights_exists: insert_or_update_statement = update(TrackMasterRights).where( TrackMasterRights.track_id == track_id)\ .values(is_owner=yes_no_enum_val) else: insert_or_update_statement = TrackMasterRights.__table__.insert().\ values(dict(track_id=track_id, is_owner=yes_no_enum_val)) insert_or_update_result = session.execute(insert_or_update_statement) session.commit() return insert_or_update_result def update_nationality_of_first_producer(session, track_id, country_id): """"Update or insert track nationality of first producer Since this is not a required field on tracks and sqlalchemy doesn't provide 'on duplicate key update' functionality we are doing this the slightly more expensive way until/unless it becomes problematic Args: session(Session): sqlalchemy session connected to art_relations track_id(int): id of track to update country_id(int): country_id indicating nationality Return: (ResultProxy): result of the update operation """ track_producer_nationality_exists = session.query( TrackProducerNationality).filter_by(track_id=track_id).first() if track_producer_nationality_exists: insert_or_update_statement = update(TrackProducerNationality).where( TrackProducerNationality.track_id == track_id)\ .values(dict(nationality_country_id=country_id)) else: insert_or_update_statement = TrackProducerNationality.__table__\ .insert().values(dict(track_id=track_id, nationality_country_id=country_id)) insert_or_update_result = session.execute(insert_or_update_statement) session.commit() return insert_or_update_result def update_rows(valid_rows): """Iterate over valid rows and update Args: valid_rows(list): list of valid row dicts Returns: (int): count of rows updated """ session = mysql.art_relations_session() countries = country.as_dict(session) updated_rows = 0 for valid_line in valid_rows: # Todo (OrCharles): maybe queue to bulk update # also maybe try/catch mark as error something_was_updated = update_line(session, valid_line, countries) if something_was_updated: updated_rows += 1 session.close() return updated_rows def update_line(session, valid_line, countries): """Perform updates against art_relations Combines local module functions, there is no return from this function Args: session(Session): mysql session valid_line(dict): pre-validated countries(dict): country_id : country_name Returns: (bool): True if anything was updated, False otherwise """ something_was_updated = False track_id = valid_line.get('Orchard Track Unique ID') song_writers_string = valid_line.get('Songwriter(s)') if song_writers_string is not None: if isinstance(song_writers_string, int): song_writers_string = str(song_writers_string) song_writers_list = song_writers_string.split('|') update_track_writer(session, track_id, song_writers_list) something_was_updated = True country_of_recording = valid_line.get('Country of Recording') if country_of_recording is not None: update_track_recording_country(session, track_id, countries[country_of_recording]) something_was_updated = True rights_ownership = valid_line.get('Master Rights') if rights_ownership is not None: update_master_rights_ownership(session, track_id, rights_ownership) something_was_updated = True first_producer_nationality = valid_line.get('Nationality of 1st Producer') if first_producer_nationality is not None: first_prod_nat = countries[first_producer_nationality] update_nationality_of_first_producer(session, track_id, first_prod_nat) something_was_updated = True return something_was_updated