def merge_users(source, target, force=False): """Merge two users together, unifying all related data :param source: source user (will be set as deleted) :param target: target user (final) """ if source.is_deleted and not force: raise ValueError( 'Source user {} has been deleted. Merge aborted.'.format(source)) if target.is_deleted: raise ValueError( 'Target user {} has been deleted. Merge aborted.'.format(target)) # Move emails to the target user primary_source_email = source.email logger.info("Target %s initial emails: %s", target, ', '.join(target.all_emails)) logger.info("Source %s emails to be linked to target %s: %s", source, target, ', '.join(source.all_emails)) UserEmail.query.filter_by(user_id=source.id).update({ UserEmail.user_id: target.id, UserEmail.is_primary: False }) # Make sure we don't have stale data after the bulk update we just performed db.session.expire_all() # Update favorites target.favorite_users |= source.favorite_users target.favorite_of |= source.favorite_of target.favorite_categories |= source.favorite_categories # Update category suggestions SuggestedCategory.merge_users(target, source) # Merge identities for identity in set(source.identities): identity.user = target # Notify signal listeners about the merge signals.users.merged.send(target, source=source) db.session.flush() # Mark source as merged source.merged_into_user = target source.is_deleted = True db.session.flush() # Restore the source user's primary email source.email = primary_source_email db.session.flush() logger.info("Successfully merged %s into %s", source, target)
def merge_users(source, target, force=False): """Merge two users together, unifying all related data :param source: source user (will be set as deleted) :param target: target user (final) """ if source.is_deleted and not force: raise ValueError('Source user {} has been deleted. Merge aborted.'.format(source)) if target.is_deleted: raise ValueError('Target user {} has been deleted. Merge aborted.'.format(target)) # Move emails to the target user primary_source_email = source.email logger.info("Target %s initial emails: %s", target, ', '.join(target.all_emails)) logger.info("Source %s emails to be linked to target %s: %s", source, target, ', '.join(source.all_emails)) UserEmail.find(user_id=source.id).update({ UserEmail.user_id: target.id, UserEmail.is_primary: False }) # Make sure we don't have stale data after the bulk update we just performed db.session.expire_all() # Update favorites target.favorite_users |= source.favorite_users target.favorite_of |= source.favorite_of target.favorite_categories |= source.favorite_categories # Update category suggestions SuggestedCategory.merge_users(target, source) # Merge identities for identity in set(source.identities): identity.user = target # Notify signal listeners about the merge signals.users.merged.send(target, source=source) db.session.flush() # Mark source as merged source.merged_into_user = target source.is_deleted = True db.session.flush() # Restore the source user's primary email source.email = primary_source_email db.session.flush() logger.info("Successfully merged %s into %s", source, target)
def merge_users(source, target, force=False): """Merge two users together, unifying all related data :param source: source user (will be set as deleted) :param target: target user (final) """ if source.is_deleted and not force: raise ValueError('Source user {} has been deleted. Merge aborted.'.format(source)) if target.is_deleted: raise ValueError('Target user {} has been deleted. Merge aborted.'.format(target)) # Merge links for link in source.linked_objects: if link.object is None: # remove link if object does no longer exist db.session.delete(link) else: link.user = target # De-duplicate links unique_links = {(link.object, link.role): link for link in target.linked_objects} to_delete = set(target.linked_objects) - set(unique_links.viewvalues()) for link in to_delete: db.session.delete(link) # Move emails to the target user primary_source_email = source.email logger.info("Target %s initial emails: %s", target, ', '.join(target.all_emails)) logger.info("Source %s emails to be linked to target %s: %s", source, target, ', '.join(source.all_emails)) UserEmail.find(user_id=source.id).update({ UserEmail.user_id: target.id, UserEmail.is_primary: False }) # Make sure we don't have stale data after the bulk update we just performed db.session.expire_all() # Update favorites target.favorite_users |= source.favorite_users target.favorite_of |= source.favorite_of target.favorite_categories |= source.favorite_categories # Update category suggestions SuggestedCategory.merge_users(target, source) # Merge identities for identity in set(source.identities): identity.user = target # Merge avatars in redis if redis_write_client: avatar_links.merge_avatars(target, source) # Notify signal listeners about the merge signals.users.merged.send(target, source=source) db.session.flush() # Mark source as merged source.merged_into_user = target source.is_deleted = True db.session.flush() # Restore the source user's primary email source.email = primary_source_email db.session.flush() logger.info("Successfully merged %s into %s", source, target)