Efficient way to "bind" a DataTable to Tabs?

Hello,

I’m trying to figure how to get things done “the Dash way”. I have a dashboard that contains a DataTable and a Tabs component below it. When rows are selected in the DataTable, I want to load some data from a database and show it in a Tab. For simplicity, let’s assume one tab per row selected.

I figure I can get this done pretty much like this:

 @app.callback(
        Output("mytabs", "children"),
        Input("my-table", "selected_row_ids"),
    )
    def get_selected_row_ids(selected_row_ids):
        tabs = []
        if selected_row_ids:
            for row_id in selected_row_ids:
                # read data for row_id from database
                # place data in new Tab

The problem with this solution is that every time a user selects a row, this code will loop over all selected rows and hit the database once for each one of them. That’s a lot of redundant I/O operations.

What might be an appropriate way to only read from the database for the newly added row? Is there an event that can give me just this row and append a tab to the Tabs?

Thanks,
urig

Hey there!

I think that the easiest solution for “diff’ing” selected_row_ids is to create a dcc.Store component that holds the ids and update it in the callback. Then you can in principle use it in the callback body to decide whether you should hit the DB or not.

Besides, if your data is relatively small, you can store both the ids and the fetched data in the same store and use selected_row_ids to filter which one of the elements in the store should be displayed in the tabs. In other words, if user selects a row, unselect it and select it again, the data is requested only once in the DB. For larger data, one option is to do server-side caching as discussed in this very nice post

2 Likes