Repository navigation
Conversation
…nteger ids - fetch_idv_child_outlays read each child contract twice: once in the join that finds the children, then again from rpt.award_search by award_id to get total_outlays, behind a parent_award_piid filter with an OR and an IN subquery - the outlays are now summed in the join itself (vw_awards is a view of rpt.award_search, which carries total_outlays); the extra filter repeated what the join already matches on - the old filter compared parent_award_piid to the request's integer id when the endpoint was called with one, so child and grandchild outlays came back null for /api/v2/idvs/amounts/<int>/; it also cut the PIID at the first underscore of a generated id - measured on the 2026-10-06 database download, for a GSA schedule IDV with 259,535 grandchild orders: the grandchild outlay query takes 0.54 s instead of 1.1 s warm, with identical results - test: an IDV tree with child and grandchild contracts, account rows under a DEFC, and a contract under another agency's PIID, requested by both id forms
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description:
/api/v2/idvs/amounts/<award_id>/returnsnullforchild_award_total_outlayandgrandchild_award_total_outlaywhen the IDV is requested by its internal (integer) award id. The same IDV requested by its generated unique award id returns the correct totals. This PR fixes that, and makes the outlay calculation do about half the work, which matters for very large IDVs such as GSA schedules.Reproduction against production (same IDV both ways;
351035969is the internal id ofCONT_IDV_75P00123A00008_7570):CONT_IDV_75A50223D00005_7505(internal id351030267) shows the same thing:1015100.0by generated id,nullby integer id. With this change both forms return the same values.Technical Details:
fetch_idv_child_outlaysinusaspending_api/idvs/v2/views/amounts.pyused to:child_award_sql/grandchild_award_sql, wrapped in a CTE;rpt.award_searchbyaward_id, only to readtotal_outlays;parent_award_piid = '<piid>' OR parent_award_piid IN (SELECT piid ... category = 'idv'), where<piid>came from splitting the request's award id on_.Step 3 caused the bug. For an integer award id,
award_id_piidwas the integer itself, so the filter comparedparent_award_piidwith something like'351035969'and matched nothing. For a generated id whose PIID contains an underscore, the split also cut the PIID short. The filter was redundant in every case: the join in step 1 already matchesparent_award_piidto the parent's PIID, together with the agency.The outlays are now summed in the join that finds the children (
child_outlay_sql,grandchild_outlay_sql). The child side of that join readsrpt.award_searchdirectly instead ofvw_awards, becausevw_awards(a view overrpt.award_search) does not exposetotal_outlays. Each child row is now visited once, and the result no longer depends on the form of the request's id.fetch_account_details_idvis unchanged apart from type annotations. I tried passing its child and grandchild sets to the DEFC query as subqueries instead of literalIN (...)lists. It was slower, because the planner estimates the grandchild join at 1 row; a pre-aggregated variant tied. Neither is included.Other changes in the touched files: imports sorted and type annotations added so that
ruff checkandruff format --checkpass on both files with the pinned ruff 0.14.14 (CI checks whole changed files), andraise NotFound(...) from Nonein the view'sexceptblock.Requirements for PR Merge:
Explain N/A in above checklist:
test_awards_idvs_amounts_v2.pygainstest_child_and_grandchild_outlays_and_account_amounts, parametrized over the integer and the generated award id. It builds an IDV with two child contracts and a child IDV with two contracts of its own, plus account rows under a DEFC and a decoy contract under another agency's PIID. Onqatthe integer-id case fails (child_award_total_outlayisNone, expected 15); with this change all four tests in the file pass.CONT_IDV_47QSEA18D008C_4732(259,535 grandchild orders since FY2024). The grandchild outlay query takes 0.54 s instead of 1.1 s with a warm cache. Child and grandchild outlay totals were identical between the old and new queries (822,974.03 and 112,719,237.77).Out-of-scope -- what this PR does not fix
For IDVs with very large grandchild trees,
idvs/amounts(andidvs/funding_rollup,idvs/activity,idvs/accounts, andidvs/awardswithtype=grandchild_awards) still return 502 after about 60 seconds. See #4861 . This fix is restricted to the other elements mentioned above.