Fix find_source_in_db crash on empty Sources table - #266
Conversation
query_region can return a columnless DataFrame when the Sources table has zero rows, which previously raised an unguarded pandas KeyError when the ra/dec columns were indexed. Now that case is detected and treated as "no spatial matches" so the first ingest into a fresh database with search_db=True no longer crashes; a KeyError from genuinely wrong ra_col_name/dec_col_name still raises AstroDBError. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016UKKrx5abQaERu4vRaZJrP
The first query_region call site (direct ra/dec) previously let a KeyError from bad ra_col_name/dec_col_name propagate unwrapped, and test_find_source_in_db_errors relies on that. The shared empty-table guard from the previous commit incorrectly wrapped it into AstroDBError in all cases. Only wrap into AstroDBError when the Sources table is actually empty; otherwise re-raise the original KeyError (first call site) or the original AstroDBError message (second, SIMBAD-resolved call site), matching pre-existing behavior. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016UKKrx5abQaERu4vRaZJrP
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #266 +/- ##
==========================================
+ Coverage 72.10% 72.35% +0.25%
==========================================
Files 19 19
Lines 1649 1664 +15
Branches 211 212 +1
==========================================
+ Hits 1189 1204 +15
Misses 379 379
Partials 81 81 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Replace the two try/except KeyError wrappers around query_region with a single early return when the Sources table has zero rows. An empty table can have no matches by definition, so this is simpler, avoids wasted SIMBAD/fuzzy search work, and keeps both query_region call sites' original error behavior completely unchanged for the non-empty-table case. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016UKKrx5abQaERu4vRaZJrP
There was a problem hiding this comment.
🟡 Changes recommended
There are a few concrete follow-ups (notably resource cleanup in the new test and aligning PR description with the implemented fix) that should be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR prevents astrodb_utils.sources.find_source_in_db from crashing when called against a brand-new database whose Sources table has zero rows, and adds a regression test to cover the empty-table scenario (Fixes #265).
Changes:
- Added an early-return guard in
find_source_in_dbwhen theSourcestable is empty. - Added a regression test that creates an empty schema-only database and asserts
find_source_in_dbreturns[]instead of raising.
File summaries
| File | Description |
|---|---|
astrodb_utils/sources.py |
Adds an empty-Sources short-circuit to avoid query_region crashing on empty tables. |
tests/test_sources.py |
Adds a regression test that exercises find_source_in_db against a freshly created empty database. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Use query(...).first() is None instead of count() == 0 to check for an empty Sources table, avoiding a full COUNT(*) scan. - Dispose the SQLAlchemy engine in test_find_source_in_db_empty_sources_table so the temporary sqlite file's handle is released. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016UKKrx5abQaERu4vRaZJrP
Summary
find_source_in_db's spatial fallback search crashed with a pandasKeyErrorwhendb.query_region(...)was called against a completely emptySourcestable (it can return a columnless DataFrame in that case), breaking the very firstingest_source(..., search_db=True)into a fresh database.Sourcestable can have no matches by definition, sofind_source_in_dbnow checks for that up front (db.query(db.Sources).first() is None) and returns[]immediately, before any name search, fuzzy search, SIMBAD resolution, orquery_regioncall. This is a single early-return guard — bothquery_regioncall sites, and their existing error behavior for genuinely badra_col_name/dec_col_namearguments, are unchanged.Fixes #265.
Test plan
test_find_source_in_db_empty_sources_table, which builds a fresh empty database from the template schema and assertsfind_source_in_dbreturns[]instead of raising; the SQLAlchemy engine is disposed in afinallyblock.KeyError) and passes with the fix.test_find_source_in_db_errors's existing expectations (badra_col_name/dec_col_nameagainst a non-empty table still raisesKeyError/AstroDBErroras before) are unaffected.pytest tests/test_sources.pyand the full suite — no new failures versus the pre-fix baseline (remaining failures are pre-existing, caused by no SIMBAD network access in this environment).python -m py_compile astrodb_utils/sources.py🤖 Generated with Claude Code
https://claude.ai/code/session_016UKKrx5abQaERu4vRaZJrP