Skip to content

Conversation

@cpsievert
Copy link
Contributor

@cpsievert cpsievert commented Jan 15, 2026

Summary

This PR adds multi-table support to QueryChat Python package, allowing users to chat with multiple related tables in a single session.

Key Features

  • Multi-table API: add_table(), remove_table(), table_names(), table("name") methods
  • TableAccessor: Per-table access via qc.table("name").df(), .sql(), .title(), .ui()
  • Per-table state: Independent SQL/title per table
  • Backwards compatible: Single-table usage remains unchanged
  • Integrates with deferred initialization: Works with the new data_source setter pattern

API Examples

# Add multiple tables
qc = QueryChat(orders_df, "orders", greeting="Hello!")
qc.add_table(customers_df, "customers", relationships={"id": "orders.customer_id"})

# Access per-table state
qc.table("orders").df()
qc.table("customers").sql()

# List tables
qc.table_names()  # ["orders", "customers"]

Core Changes

File Changes
_querychat_base.py _data_sources dict storage, add_table(), remove_table(), table_names(), table()
_table_accessor.py New file with TableAccessor class
_system_prompt.py Multi-source support with relationships
tools.py Table parameter on update/reset tools, dict-based data sources
prompts/*.md Multi-table instructions and table parameter docs

Design Document

See docs/plans/2025-01-14-multi-table-design.md for the full design specification.

Test plan

  • All 292 tests pass (including new deferred initialization tests from main)
  • New tests in test_multi_table.py cover storage, add/remove, accessor, ambiguity errors
  • Ruff linting passes
  • Manual testing with multi-table app

🤖 Generated with Claude Code

@cpsievert cpsievert marked this pull request as draft January 15, 2026 21:10
Base automatically changed from feat/py-ibis-source to main January 16, 2026 22:41
@cpsievert cpsievert force-pushed the feat/py-multi-table branch 2 times, most recently from 76e009c to 193c2e1 Compare January 26, 2026 17:39
Add the ability to register multiple tables with a QueryChat instance,
enabling cross-table queries and per-table state management.

- **Storage**: Change from single `_data_source` to `_data_sources` dict
- **API**: Add `table_names()`, `table()`, `add_table()`, `remove_table()` methods
- **TableAccessor**: New class for per-table access (`qc.table("name").df()`)
- **Backwards compatible**: Single-table usage works unchanged

- `update_dashboard` and `reset_dashboard` now include table name parameter
- `tool_query` supports querying across multiple tables
- Updated tool prompts to guide LLM on multi-table operations

- Schema section now includes all registered tables
- Added relationship hints for JOINs
- Table descriptions can be provided for LLM context

All frameworks (Shiny, Dash, Streamlit, Gradio) updated to work with
the new dict-based storage while maintaining single-table behavior.

- Added 22 new tests for multi-table functionality
- Updated existing tests for new internal structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants