Skip to content

Commit bc4828b

Browse files
committed
fix: reload dataset tables when connection changes in tabs
Extract _sync_table_catalog on TableBrowser, add demo watcher cells so Marimo reruns the datasets panel when the connection dropdown changes, and improve empty-state hints.
1 parent f9a1ed7 commit bc4828b

3 files changed

Lines changed: 63 additions & 17 deletions

File tree

examples/demo.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,25 @@ def _(mo):
5656

5757

5858
@app.cell
59-
def _(browser, editor, history, mo, recent, status, workspace):
59+
def _(browser):
60+
# Register connection/table widget deps so Marimo reruns layout cells on change.
61+
if browser._conn_pick is not None:
62+
_ = browser._conn_pick.value
63+
_ = browser.table_pick.value
64+
return
65+
66+
67+
@app.cell
68+
def _(browser):
69+
return (browser.ui,)
70+
71+
72+
@app.cell
73+
def _(browser_ui, editor, history, mo, recent, status, workspace):
6074
mo.ui.tabs({
6175
"Workspaces": workspace.ui,
6276
"Connections": status,
63-
"Datasets": browser.ui,
77+
"Datasets": browser_ui,
6478
"SQL query": editor.ui,
6579
"Recent results": recent.ui,
6680
"Run history": history,

hotdata_marimo/table_browser.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def __init__(
4343
)
4444

4545
self._table_pick_ctx: str | None = None
46+
self._rebuilt_table_pick_this_run = False
4647
self._init_table_pick()
4748

4849
def _init_table_pick(self) -> None:
@@ -53,6 +54,7 @@ def _init_table_pick(self) -> None:
5354
)
5455
self._empty_catalog = True
5556
self._all_names = []
57+
self._table_pick_ctx = ""
5658
return
5759

5860
names = self._names_for_active_connection()
@@ -120,35 +122,42 @@ def selected_table(self) -> str | None:
120122
v = self.table_pick.value
121123
return v if v else None
122124

123-
@property
124-
def ui(self):
125-
self._rebuilt_table_pick_this_run = False
126-
125+
def _sync_table_catalog(self) -> None:
126+
"""Refresh the table dropdown when the active connection changes."""
127127
if self._conn_pick is not None:
128-
_ = self._conn_pick.value
129-
128+
_ = self._conn_pick.value # type: ignore[attr-defined]
130129
cid = self._active_connection_id()
131-
names = self._names_for_active_connection()
130+
if not cid:
131+
return
132+
if cid == self._table_pick_ctx:
133+
return
134+
self._rebuild_table_pick(self._names_for_active_connection())
132135

133-
if cid and cid != self._table_pick_ctx:
134-
self._rebuild_table_pick(names)
136+
@property
137+
def ui(self):
138+
self._rebuilt_table_pick_this_run = False
139+
self._sync_table_catalog()
135140

136141
if not self._rebuilt_table_pick_this_run:
137142
_ = self.table_pick.value
138143

139144
sel = None if self._rebuilt_table_pick_this_run else self.selected_table
145+
cid = self._active_connection_id()
140146
conn_header = (
141147
mo.md(f"**Connection** `{self._active_connection_id()}`")
142148
if self._active_connection_id()
143149
else None
144150
)
145151
if not sel:
146-
hint = (
147-
"_No tables returned from the information schema. "
148-
"Try refreshing a connection in Hotdata._"
149-
if self._empty_catalog
150-
else "Choose a table below (search inside the dropdown when needed)."
151-
)
152+
if self._conn_pick is not None and not cid:
153+
hint = "Choose a connection above to load tables."
154+
elif self._empty_catalog:
155+
hint = (
156+
"_No tables returned from the information schema. "
157+
"Try refreshing a connection in Hotdata._"
158+
)
159+
else:
160+
hint = "Choose a table below (search inside the dropdown when needed)."
152161
stack = [
153162
mo.md(
154163
f"**Workspace** `{self._client.workspace_id}` — {hint}"

tests/test_hotdata_marimo.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from hotdata_marimo._options import connection_options, unique_label_options
1111
from hotdata_marimo.display import connections_panel
1212
from hotdata_marimo.sql_engine import HotdataMarimoEngine
13+
from hotdata_marimo.table_browser import TableBrowser
1314
from hotdata_marimo.workspace_selector import WorkspaceSelector, workspace_selector_from_env
1415
from marimo._types.ids import VariableName
1516

@@ -127,6 +128,28 @@ def test_connections_panel_lists_connections(mock_client):
127128
assert panel is not None
128129

129130

131+
def test_table_browser_rebuilds_tables_when_connection_changes(mock_client):
132+
pick = MagicMock()
133+
pick.value = ""
134+
mock_client.list_qualified_table_names.return_value = []
135+
136+
with patch(
137+
"hotdata_marimo.table_browser.resolve_connection_picker",
138+
return_value=(pick, None),
139+
):
140+
browser = TableBrowser(mock_client)
141+
142+
browser._sync_table_catalog()
143+
assert browser._table_pick_ctx == ""
144+
145+
pick.value = "conn_1"
146+
mock_client.list_qualified_table_names.return_value = ["azure.public.customer"]
147+
browser._sync_table_catalog()
148+
assert browser._table_pick_ctx == "conn_1"
149+
assert browser._all_names == ["azure.public.customer"]
150+
assert not browser._empty_catalog
151+
152+
130153
def test_workspace_selector_from_env_requires_api_key(monkeypatch: pytest.MonkeyPatch):
131154
monkeypatch.delenv("HOTDATA_API_KEY", raising=False)
132155
with pytest.raises(RuntimeError, match="HOTDATA_API_KEY"):

0 commit comments

Comments
 (0)