'Generates record dicts from the data sequence.
The result is a generator of dicts mapping field names to raw
(unconverted, unvalidated) values.
For relational fields, if sub-fields were provided the value will be
a list of sub-records
The following sub-fields may be set on the record (by key):
* None is the name_get for the record (to use with name_create/name_search)
* "id" is the External ID for the record
* ".id" is the Database ID for the record'

@api.model
def _extract_records(self, fields_, data, log=(lambda a: None)):

    fields = dict(self._fields)
    fields = self._add_fake_fields(fields)
    is_relational = (lambda field: fields[field].relational)
    get_o2m_values = itemgetter_tuple([index for (index, fnames) in enumerate(fields_) if (fields[fnames[0]].type == 'one2many')])
    get_nono2m_values = itemgetter_tuple([index for (index, fnames) in enumerate(fields_) if (fields[fnames[0]].type != 'one2many')])
    def only_o2m_values(row):
        return (any(get_o2m_values(row)) and (not any(get_nono2m_values(row))))
    index = 0
    while (index < len(data)):
        row = data[index]
        record = {fnames[0]: value for (fnames, value) in itertools.izip(fields_, row) if (not is_relational(fnames[0]))}
        record_span = itertools.takewhile(only_o2m_values, itertools.islice(data, (index + 1), None))
        record_span = list(itertools.chain([row], record_span))
        for relfield in set((fnames[0] for fnames in fields_ if is_relational(fnames[0]))):
            comodel = self.env[fields[relfield].comodel_name]
            (indices, subfields) = zip(*((index, (fnames[1:] or [None])) for (index, fnames) in enumerate(fields_) if (fnames[0] == relfield)))
            relfield_data = filter(any, map(itemgetter_tuple(indices), record_span))
            record[relfield] = [subrecord for (subrecord, _subinfo) in comodel._extract_records(subfields, relfield_data, log=log)]
        (yield (record, {'rows': {'from': index, 'to': ((index + len(record_span)) - 1)}}))
        index += len(record_span)
