code: def to_frame(self, columns=None):
          
          extra_cols = _columns_for_table(self.name)
  
          if columns is not None:
              columns = [columns] if isinstance(columns, str) else columns
              columns = set(columns)
              set_extra_cols = set(extra_cols)
              local_cols = set(self.local.columns) & columns - set_extra_cols
              df = self.local[list(local_cols)].copy()
              extra_cols = {k: extra_cols[k] for k in (columns & set_extra_cols)}
          else:
              df = self.local.copy()
  
          with log_start_finish(
                  'computing {!r} columns for table {!r}'.format(
                      len(extra_cols), self.name),
                  logger):
              for name, col in extra_cols.items():
                  with log_start_finish(
                          'computing column {!r} for table {!r}'.format(
                              name, self.name),
                          logger):
                      df[name] = col()
  
          return df
docs: Make a DataFrame with the given columns.
  
          Will always return a copy of the underlying table.
  
          Parameters
          ----------
          columns : sequence or string, optional
              Sequence of the column names desired in the DataFrame. A string
              can also be passed if only one column is desired.
              If None all columns are returned, including registered columns.
  
          Returns
          -------
          frame : pandas.DataFrame