'Set fields for a particular XBlock.
Arguments:
username: The name of the user whose state should be retrieved
block_keys_to_state (dict): A dict mapping UsageKeys to state dicts.
Each state dict maps field names to values. These state dicts
are overlaid over the stored state. To delete fields, use
:meth:`delete` or :meth:`delete_many`.
scope (Scope): The scope to load data from'

def set_many(self, username, block_keys_to_state, scope=Scope.user_state):

    if (scope != Scope.user_state):
        raise ValueError('Only    Scope.user_state    is    supported')
    self._nr_stat_increment('set_many', 'calls')
    if ((self.user is not None) and (self.user.username == username)):
        user = self.user
    else:
        user = User.objects.get(username=username)
    if user.is_anonymous():
        return
    evt_time = time()
    for (usage_key, state) in block_keys_to_state.items():
        (student_module, created) = StudentModule.objects.get_or_create(student=user, course_id=usage_key.course_key, module_state_key=usage_key, defaults={'state': json.dumps(state), 'module_type': usage_key.block_type})
        num_fields_before = num_fields_after = num_new_fields_set = len(state)
        num_fields_updated = 0
        if (not created):
            if (student_module.state is None):
                current_state = {}
            else:
                current_state = json.loads(student_module.state)
            num_fields_before = len(current_state)
            current_state.update(state)
            num_fields_after = len(current_state)
            student_module.state = json.dumps(current_state)
            try:
                with transaction.atomic():
                    student_module.save(force_update=True)
            except IntegrityError:
                log.warning('set_many:    IntegrityError    for    student    {}    -    course_id    {}    -    usage    key    {}'.format(user, repr(unicode(usage_key.course_key)), usage_key))
                log.warning('set_many:    All    {}    block    keys:    {}'.format(len(block_keys_to_state), block_keys_to_state.keys()))
        self._nr_block_stat_accumulate('set_many', usage_key.block_type, 'size', len(student_module.state))
        if created:
            self._ddog_increment(evt_time, 'set_many.state_created')
            self._nr_block_stat_increment('set_many', usage_key.block_type, 'blocks_created')
        else:
            self._ddog_increment(evt_time, 'set_many.state_updated')
            self._nr_block_stat_increment('set_many', usage_key.block_type, 'blocks_updated')
        self._ddog_histogram(evt_time, 'set_many.fields_in', len(state))
        num_new_fields_set = (num_fields_after - num_fields_before)
        self._ddog_histogram(evt_time, 'set_many.fields_set', num_new_fields_set)
        num_fields_updated = max(0, (len(state) - num_new_fields_set))
        self._ddog_histogram(evt_time, 'set_many.fields_updated', num_fields_updated)
    finish_time = time()
    duration = ((finish_time - evt_time) * 1000)
    self._ddog_histogram(evt_time, 'set_many.blks_updated', len(block_keys_to_state))
    self._ddog_histogram(evt_time, 'set_many.response_time', duration)
    self._nr_stat_accumulate('set_many', 'duration', duration)
