Tabulator, fetching page data as needed from large table, index error beyond page 1

Hi, I’m trying to display a large table with Tabulator, by the page, but not retrieve entire data initially, easier on the database and also shows the latest.

Scenario:

Let’s say there’s a million rows in the database. Initially, on page load, display a page data (say 5 rows), with all the pagination buttons. When the user clicks on page 2, trigger the page event, retrieve the fresh data from the database, and tabulator shows the new data on page 2.

For pagination=‘remote’ examples, the tabulator is created using a dataframe that’s already has all the data so Tabulator can calculate the pagination information. The remote pagination was probably meant to solve the “don’t load everything on the browser” issue.
I’m trying to avoid retrieving the entire dataset initially.

What I’ve tried:

  1. Load all the data into dataframe, create the tabulator. It works with pagination=‘remote’. So it’s not a coding issue.

image

3.Create a dataframe with only 5 of the rows but then pagination buttons won’t show.
image

  1. Pagination=‘remote’. No sort or filtering. Create a dummy dataframe with a million rows of empty data, matching the datatype, use tabulator.patch() in page event to update the window of data in the page. Getting an index error on page 2. Tabulator refuses to allow patching of any index above the first page, ValueError: Out-of bounds index 6. Example of patch work so far because the indexes were low numbers
def get_page_data(page_num,page_size):
    # simulate retrieving a page of data from database
    offset = (page_num - 1) * page_size
    df = pd.DataFrame(
        data={'A': [f"A{i+offset}" for i in range(page_size)]},
        index=[i+offset for i in range(page_size)]
    )
    return df
    
def on_page_change(event):
    page_df = get_page_data(event.new, event.obj.page_size)
    event.obj.patch(page_df,as_index=True)

# create the large empty df
large_df = pd.DataFrame({'A': [''] * 100000})
tabulator = pn.widgets.Tabulator(large_df, pagination='remote', page_size=5)

# patch the first page so it shows data
tabulator.patch(get_page_data(1, 5),as_index=True)

# set up watcher
tabulator.param.watch(on_page_change, "page")
tabulator

Here’s the error:

Traceback (most recent call last):
  File "/opt/venv/lib/python3.12/site-packages/pyviz_comms/__init__.py", line 341, in _handle_msg
    self._on_msg(msg)
  File "/opt/venv/lib/python3.12/site-packages/panel/viewable.py", line 500, in _on_msg
    doc.unhold()
  File "/opt/venv/lib/python3.12/site-packages/bokeh/document/document.py", line 776, in unhold
    self.callbacks.unhold()
  File "/opt/venv/lib/python3.12/site-packages/bokeh/document/callbacks.py", line 441, in unhold
    self.trigger_on_change(event)
  File "/opt/venv/lib/python3.12/site-packages/bokeh/document/callbacks.py", line 418, in trigger_on_change
    invoke_with_curdoc(doc, event.callback_invoker)
  File "/opt/venv/lib/python3.12/site-packages/bokeh/document/callbacks.py", line 453, in invoke_with_curdoc
    return f()
           ^^^
  File "/opt/venv/lib/python3.12/site-packages/bokeh/util/callback_manager.py", line 174, in invoke
    callback(attr, old, new)
  File "/opt/venv/lib/python3.12/site-packages/panel/reactive.py", line 563, in _comm_change
    state._handle_exception(e)
  File "/opt/venv/lib/python3.12/site-packages/panel/io/state.py", line 488, in _handle_exception
    raise exception
  File "/opt/venv/lib/python3.12/site-packages/panel/reactive.py", line 561, in _comm_change
    self._schedule_change(doc, comm)
  File "/opt/venv/lib/python3.12/site-packages/panel/reactive.py", line 543, in _schedule_change
    self._change_event(doc)
  File "/opt/venv/lib/python3.12/site-packages/panel/reactive.py", line 539, in _change_event
    self._process_events(events)
  File "/opt/venv/lib/python3.12/site-packages/panel/widgets/tables.py", line 1385, in _process_events
    return super()._process_events(events)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.12/site-packages/panel/reactive.py", line 1462, in _process_events
    super()._process_events(events)  # noqa
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.12/site-packages/panel/reactive.py", line 493, in _process_events
    raise e
  File "/opt/venv/lib/python3.12/site-packages/panel/reactive.py", line 474, in _process_events
    self.param.update(**self_params)
  File "/opt/venv/lib/python3.12/site-packages/param/parameterized.py", line 2406, in update
    restore = dict(self_._update(arg, **kwargs))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.12/site-packages/param/parameterized.py", line 2439, in _update
    self_._batch_call_watchers()
  File "/opt/venv/lib/python3.12/site-packages/param/parameterized.py", line 2624, in _batch_call_watchers
    self_._execute_watcher(watcher, events)
  File "/opt/venv/lib/python3.12/site-packages/param/parameterized.py", line 2586, in _execute_watcher
    watcher.fn(*args, **kwargs)
  File "/tmp/ipykernel_3110/1320224439.py", line 12, in on_page_change
    event.obj.patch(page_df,as_index=False)
  File "/opt/venv/lib/python3.12/site-packages/panel/widgets/tables.py", line 905, in patch
    self.patch(patch_value_dict, as_index=as_index)
  File "/opt/venv/lib/python3.12/site-packages/panel/widgets/tables.py", line 941, in patch
    self._patch(patches)
  File "/opt/venv/lib/python3.12/site-packages/panel/util/__init__.py", line 342, in wrapped
    fn(self, *args, **kwargs)
  File "/opt/venv/lib/python3.12/site-packages/panel/widgets/tables.py", line 1714, in _patch
    super()._patch(patch)
  File "/opt/venv/lib/python3.12/site-packages/panel/util/__init__.py", line 342, in wrapped
    fn(self, *args, **kwargs)
  File "/opt/venv/lib/python3.12/site-packages/panel/reactive.py", line 1112, in _patch
    m.source.patch(patch)
  File "/opt/venv/lib/python3.12/site-packages/bokeh/models/sources.py", line 700, in patch
    raise ValueError(f"Out-of bounds index ({ind}) in patch for column: {name}")
ValueError: Out-of bounds index (6) in patch for column: A

Appreciate any suggestions.