docs: def walk_and_clean(data):
      """
      Recursively walks list of dicts (which may themselves embed lists and dicts),
      transforming namedtuples to OrderedDicts and
      using ``clean_key_name(k)`` to make keys into SQL-safe column names
  
      >>> data = [{'a': 1}, [{'B': 2}, {'B': 3}], {'F': {'G': 4}}]
      >>> pprint(walk_and_clean(data))
          [OrderedDict([('a', 1)]),
           [OrderedDict([('b', 2)]), OrderedDict([('b', 3)])],
            OrderedDict([('f', OrderedDict([('g', 4)]))])]
      """
      # transform namedtuples to OrderedDicts
      if hasattr(data, '_fields'):
          data = OrderedDict((k,v) for (k,v) in zip(data._fields, data))
      # Recursively clean up child dicts and lists
      if hasattr(data, 'items') and hasattr(data, '__setitem__'):
          for (key, val) in data.items():
              data[key] = walk_and_clean(val)
      elif isinstance(data, list) or isinstance(data, tuple) \
           or hasattr(data, '__next__') or hasattr(data, 'next'):
          data = [walk_and_clean(d) for d in data]
  
      # Clean up any keys in this dict itself
      if hasattr(data, 'items'):
          original_keys = data.keys()
          tup = ((clean_key_name(k), v) for (k, v) in data.items())
          data = OrderedDict(tup)
          if len(data) < len(original_keys):
              raise KeyError('Cleaning up %s created duplicates' %
                             original_keys)
      return data