docs: def unnest_children(data, parent_name='', pk_name=None, force_pk=False):
      """
      For each ``key`` in each row of ``data`` (which must be a list of dicts),
      unnest any dict values into ``parent``, and remove list values into separate lists.
  
      Return (``data``, ``pk_name``, ``children``, ``child_fk_names``) where
  
      ``data``
        the transformed input list
      ``pk_name``
        field name of ``data``'s (possibly new) primary key
      ``children``
        a defaultdict(list) of data extracted from child lists
      ``child_fk_names``
        dict of the foreign key field name in each child
  
      """
      possible_fk_names = ['%s_id' % parent_name, '_%s_id' % parent_name, 'parent_id', ]
      if pk_name:
          possible_fk_names.insert(0, '%s_%s' % (parent_name, pk_name.strip('_')))
      children = defaultdict(list)
      field_names_used_by_children = defaultdict(set)
      child_fk_names = {}
      parent = ParentTable(data, parent_name, pk_name=pk_name, force_pk=force_pk)
      for row in parent:
          try:
              for (key, val) in row.items():
                  if hasattr(val, 'items'):
                      unnest_child_dict(parent=row, key=key, parent_name=parent_name)
                  elif isinstance(val, list) or isinstance(val, tuple):
                      # force listed items to be dicts, not scalars
                      row[key] = [v if hasattr(v, 'items') else {key: v} for v in val]
          except AttributeError:
              raise TypeError('Each row should be a dictionary, got %s: %s' % (type(row), row))
          for (key, val) in row.items():
              if isinstance(val, list) or isinstance(val, tuple):
                  for child in val:
                      field_names_used_by_children[key].update(set(child.keys()))
      for (child_name, names_in_use) in field_names_used_by_children.items():
          if not parent.pk:
              parent.assign_pk()
          for fk_name in possible_fk_names:
              if fk_name not in names_in_use:
                  break
          else:
              raise Exception("Cannot find unused field name in %s.%s to use as foreign key"
                              % (parent_name, child_name))
          child_fk_names[child_name] = fk_name
          for row in parent:
              if child_name in row:
                  for child in row[child_name]:
                      child[fk_name] = row[parent.pk.name]
                      children[child_name].append(child)
                  row.pop(child_name)
      # TODO: What if rows have a mix of scalar / list / dict types?
      return (parent, parent.pk.name if parent.pk else None, children, child_fk_names)