jk200201 commited on
Commit
ebfc4ea
·
verified ·
1 Parent(s): 28459d0

Add Browse data panel (table dropdown + row preview)

Browse files
Files changed (1) hide show
  1. app.py +51 -1
app.py CHANGED
@@ -223,6 +223,47 @@ def schema_map_html(uploaded_db: str | None) -> str:
223
  return f"<p>Could not read database: {html.escape(str(exc))}</p>"
224
 
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  def prefetch_weights() -> None:
227
  """Download weights to disk at startup (CPU, no GPU timer).
228
 
@@ -303,6 +344,10 @@ with gr.Blocks(title="LocalSQL") as demo:
303
  with gr.Accordion("What's in this database? (tables, columns, keys)", open=True):
304
  schema_map = gr.HTML()
305
 
 
 
 
 
306
  with gr.Row():
307
  with gr.Column(scale=1):
308
  uploaded_db = gr.File(
@@ -346,10 +391,15 @@ with gr.Blocks(title="LocalSQL") as demo:
346
  inputs=[question, evidence, run_sql, uploaded_db],
347
  outputs=[sql, rows, status, schema, reasoning],
348
  )
349
- # Refresh the schema map + raw DDL for whichever database is selected.
 
 
 
 
350
  for trigger in (uploaded_db.change, demo.load):
351
  trigger(schema_map_html, inputs=[uploaded_db], outputs=[schema_map])
352
  trigger(show_schema, inputs=[uploaded_db], outputs=[schema])
 
353
 
354
 
355
  ensure_sample_db()
 
223
  return f"<p>Could not read database: {html.escape(str(exc))}</p>"
224
 
225
 
226
+ def _list_tables(db_path: str) -> list[str]:
227
+ con = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
228
+ tables = [
229
+ r[0] for r in con.execute(
230
+ "SELECT name FROM sqlite_master WHERE type='table' "
231
+ "AND name NOT LIKE 'sqlite_%' ORDER BY name"
232
+ )
233
+ ]
234
+ con.close()
235
+ return tables
236
+
237
+
238
+ def browse_table(uploaded_db: str | None, table_name: str | None) -> pd.DataFrame:
239
+ """Return the first rows of the selected table (read-only preview)."""
240
+ if not table_name:
241
+ return pd.DataFrame()
242
+ db_path, err = resolve_db(uploaded_db)
243
+ if err:
244
+ return pd.DataFrame()
245
+ try:
246
+ con = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
247
+ # table_name comes from our own dropdown (populated from sqlite_master).
248
+ cur = con.execute(f'SELECT * FROM "{table_name}" LIMIT 10')
249
+ cols = [d[0] for d in cur.description]
250
+ data = cur.fetchall()
251
+ con.close()
252
+ return pd.DataFrame(data, columns=cols)
253
+ except Exception: # noqa: BLE001
254
+ return pd.DataFrame()
255
+
256
+
257
+ def refresh_browser(uploaded_db: str | None):
258
+ """Repopulate the table dropdown and preview the first table's rows."""
259
+ db_path, err = resolve_db(uploaded_db)
260
+ if err:
261
+ return gr.update(choices=[], value=None), pd.DataFrame()
262
+ tables = _list_tables(db_path)
263
+ first = tables[0] if tables else None
264
+ return gr.update(choices=tables, value=first), browse_table(uploaded_db, first)
265
+
266
+
267
  def prefetch_weights() -> None:
268
  """Download weights to disk at startup (CPU, no GPU timer).
269
 
 
344
  with gr.Accordion("What's in this database? (tables, columns, keys)", open=True):
345
  schema_map = gr.HTML()
346
 
347
+ with gr.Accordion("Browse data (peek at rows)", open=False):
348
+ table_dropdown = gr.Dropdown(label="Table", choices=[], interactive=True)
349
+ browse_df = gr.Dataframe(label="First 10 rows", interactive=False)
350
+
351
  with gr.Row():
352
  with gr.Column(scale=1):
353
  uploaded_db = gr.File(
 
391
  inputs=[question, evidence, run_sql, uploaded_db],
392
  outputs=[sql, rows, status, schema, reasoning],
393
  )
394
+ # Preview rows when the user picks a table.
395
+ table_dropdown.change(
396
+ browse_table, inputs=[uploaded_db, table_dropdown], outputs=[browse_df]
397
+ )
398
+ # Refresh the schema map, raw DDL, and table browser for the selected database.
399
  for trigger in (uploaded_db.change, demo.load):
400
  trigger(schema_map_html, inputs=[uploaded_db], outputs=[schema_map])
401
  trigger(show_schema, inputs=[uploaded_db], outputs=[schema])
402
+ trigger(refresh_browser, inputs=[uploaded_db], outputs=[table_dropdown, browse_df])
403
 
404
 
405
  ensure_sample_db()