Skip to content

Commit f1f6188

Browse files
committed
feat: add database= parameter to sql engine and editor for managed database scoping
Pass database= to client.execute_sql() so queries are scoped to a managed database via the X-Database-Id header (hotdata-runtime>=0.2.1). - HotdataMarimoEngine: add default_database= constructor param, pass to execute() - SqlEditor: add database= constructor param, pass to both execute_sql calls - ManagedDatabaseWriter: use description= kwarg matching ManagedDatabase v0.2.0 API - Fix test_databases_marimo.py syntax error and update assertions
1 parent 7fb5eb7 commit f1f6188

6 files changed

Lines changed: 28 additions & 22 deletions

File tree

hotdata_marimo/databases.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def databases_panel(client: HotdataClient):
4747
gap=1,
4848
)
4949
rows: list[dict[str, object]] = [
50-
{"name": db.name, "id": db.id, "sql_prefix": f"{db.name}.{{schema}}.{{table}}"}
50+
{"description": db.description or db.id, "id": db.id, "sql_prefix": f"{db.id}.{{schema}}.{{table}}"}
5151
for db in dbs
5252
]
5353
return mo.vstack(
@@ -127,8 +127,8 @@ def _rebuild_database_pick(self) -> None:
127127
message="(create one first)",
128128
)
129129
return
130-
options = {db.name: db.name for db in dbs}
131-
value = current if current in options else next(iter(options))
130+
options = {db.description or db.id: db.id for db in dbs}
131+
value = current if current in options.values() else next(iter(options.values()))
132132
self.database = mo.ui.dropdown(
133133
options=options,
134134
label="Database",
@@ -153,7 +153,7 @@ def _maybe_create(self) -> None:
153153
tables = _parse_table_names(self.tables.value)
154154
try:
155155
self._create_result = self._client.create_managed_database(
156-
db_name,
156+
description=db_name,
157157
schema=schema,
158158
tables=tables or None,
159159
)
@@ -209,7 +209,7 @@ def result_panel(self):
209209
db = self._create_result
210210
return mo.callout(
211211
mo.md(
212-
f"Created **{db.name}** (`{db.id}`). "
212+
f"Created **{db.description or db.id}** (`{db.id}`). "
213213
"Load parquet into a declared table below."
214214
),
215215
kind="success",

hotdata_marimo/sql_editor.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ def __init__(
2020
default_sql: str = "",
2121
label: str = "SQL",
2222
run_label: str = "Run on Hotdata",
23+
database: str | None = None,
2324
) -> None:
2425
self._client = client
26+
self._database = database
2527
self.sql = mo.ui.text_area(default_sql, label=label)
2628
self.run = mo.ui.button(
2729
value=0,
@@ -103,7 +105,7 @@ def _execute_or_cached(self) -> QueryResult | None:
103105
title="Running on Hotdata",
104106
subtitle="Re-running last query and waiting for results…",
105107
):
106-
result = self._client.execute_sql(self._cached_sql or "")
108+
result = self._client.execute_sql(self._cached_sql or "", database=self._database)
107109
self._result_cache = result
108110
self._last_rerun_n = rerun_n
109111
return result
@@ -113,7 +115,7 @@ def _execute_or_cached(self) -> QueryResult | None:
113115
title="Running on Hotdata",
114116
subtitle="Executing query and waiting for results…",
115117
):
116-
result = self._client.execute_sql(sql_text)
118+
result = self._client.execute_sql(sql_text, database=self._database)
117119
self._result_cache = result
118120
self._cached_sql = sql_text
119121
self._last_run_n = run_n
@@ -195,7 +197,8 @@ def sql_editor(
195197
default_sql: str = "",
196198
label: str = "SQL",
197199
run_label: str = "Run on Hotdata",
200+
database: str | None = None,
198201
) -> SqlEditor:
199202
return SqlEditor(
200-
client, default_sql=default_sql, label=label, run_label=run_label
203+
client, default_sql=default_sql, label=label, run_label=run_label, database=database
201204
)

hotdata_marimo/sql_engine.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ def __init__(
3737
self,
3838
connection: HotdataClient,
3939
engine_name: VariableName | None = None,
40+
*,
41+
default_database: str | None = None,
4042
) -> None:
4143
super().__init__(connection, engine_name)
4244
self._connections_cache: list[Any] | None = None
45+
self._default_database = default_database
4346

4447
@property
4548
def source(self) -> str:
@@ -291,7 +294,7 @@ def get_table_details(
291294
)
292295

293296
def execute(self, query: str) -> Any:
294-
qr = self._connection.execute_sql(query)
297+
qr = self._connection.execute_sql(query, database=self._default_database)
295298
fmt = self.sql_output_format()
296299

297300
def to_polars() -> Any:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ readme = "README.md"
1010
requires-python = ">=3.10"
1111
license = { text = "MIT" }
1212
dependencies = [
13-
"hotdata-runtime>=0.1.1",
13+
"hotdata-runtime>=0.2.1",
1414
"hotdata>=0.2.0",
1515
"marimo>=0.10.0",
1616
]

tests/test_databases_marimo.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def test_databases_panel_empty_state(mock_client):
1717

1818
def test_databases_panel_lists_managed_databases(mock_client):
1919
mock_client.list_managed_databases.return_value = [
20-
ManagedDatabase(id="c1", name="sales", source_type="managed"),
20+
ManagedDatabase(id="c1", description="sales", default_connection_id="conn_c1"),
2121
]
2222
with patch("hotdata_marimo.databases.mo.vstack", return_value="panel"), patch(
2323
"hotdata_marimo.databases.mo.md", side_effect=lambda x: x
@@ -30,8 +30,8 @@ def test_managed_database_writer_creates_database(mock_client):
3030
mock_client.list_managed_databases.return_value = []
3131
mock_client.create_managed_database.return_value = ManagedDatabase(
3232
id="conn_new",
33-
name="sales",
34-
source_type="managed",
33+
description="sales",
34+
default_connection_id="conn_c1",
3535
)
3636
create = MagicMock()
3737
create.value = 1
@@ -71,7 +71,7 @@ def test_managed_database_writer_creates_database(mock_client):
7171
panel = writer.result_panel
7272

7373
mock_client.create_managed_database.assert_called_once_with(
74-
"sales",
74+
description="sales",
7575
schema="public",
7676
tables=["orders", "customers"],
7777
)
@@ -80,7 +80,7 @@ def test_managed_database_writer_creates_database(mock_client):
8080

8181
def test_managed_database_writer_loads_parquet(mock_client):
8282
mock_client.list_managed_databases.return_value = [
83-
ManagedDatabase(id="c1", name="sales", source_type="managed"),
83+
ManagedDatabase(id="c1", description="sales", default_connection_id="conn_c1"),
8484
]
8585
mock_client.upload_parquet.return_value = "upl_1"
8686
mock_client.load_managed_table.return_value = LoadManagedTableResult(

uv.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)