docs: def _to_records(self, df, string_max_len=None, forced_dtype=None):
          """
          Similar to DataFrame.to_records()
          Differences:
              Attempt type conversion for pandas columns stored as objects (e.g. strings),
              as we can only store primitives in the ndarray.
              Use dtype metadata to store column and index names.
  
          string_max_len: integer - enforces a string size on the dtype, if any
                                    strings exist in the record
          """
  
          index_names, ix_vals, metadata = self._index_to_records(df)
          columns, column_vals, multi_column = self._column_data(df)
  
          if "" in columns:
              raise ArcticException("Cannot use empty string as a column name.")
  
          if multi_column is not None:
              metadata['multi_column'] = multi_column
          metadata['columns'] = columns
          names = index_names + columns
  
          arrays = []
          for arr, name in zip(ix_vals + column_vals, index_names + columns):
              arrays.append(_to_primitive(arr, string_max_len,
                                          forced_dtype=None if forced_dtype is None else forced_dtype[name]))
  
          if forced_dtype is None:
              dtype = np.dtype([(str(x), v.dtype) if len(v.shape) == 1 else (str(x), v.dtype, v.shape[1])
                                for x, v in zip(names, arrays)],
                               metadata=metadata)
          else:
              dtype = forced_dtype
  
          # The argument names is ignored when dtype is passed
          rtn = np.rec.fromarrays(arrays, dtype=dtype, names=names)
          # For some reason the dtype metadata is lost in the line above
          # and setting rtn.dtype to dtype does not preserve the metadata
          # see https://github.com/numpy/numpy/issues/6771
  
          return (rtn, dtype)