Skip to content

Commit 49e971f

Browse files
authored
Merge pull request #2874 from fedspendingtransparency/qat
Sprint 121 Prod Deploy
2 parents b2346ba + 3c05814 commit 49e971f

File tree

11 files changed

+1077
-5
lines changed

11 files changed

+1077
-5
lines changed

usaspending_api/database_scripts/job_archive/management/commands/generate_cares_act_test_data_sqls/clone_submissions.sql

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ insert into submission_attributes (
4343
update_date,
4444
reporting_agency_name,
4545
published_date,
46+
is_final_balances_for_fy,
47+
submission_window_id,
4648
_base_submission_id
4749
)
4850
select
@@ -59,6 +61,8 @@ select
5961
update_date,
6062
reporting_agency_name,
6163
'{reporting_period_end}'::date - interval '5 days', -- published_date
64+
is_final_balances_for_fy,
65+
(SELECT id FROM dabs_submission_window_schedule dsws WHERE dsws.submission_fiscal_year = {destination_fiscal_year} AND dsws.submission_fiscal_month = {destination_fiscal_period} AND dsws.is_quarter = FALSE) AS submission_window_id,
6266
submission_id -- _base_submission_id
6367
from
6468
submission_attributes
@@ -275,7 +279,8 @@ insert into financial_accounts_by_awards (
275279
program_activity_id,
276280
submission_id,
277281
treasury_account_id,
278-
disaster_emergency_fund_code
282+
disaster_emergency_fund_code,
283+
distinct_award_key
279284
)
280285
select
281286
f.data_source,
@@ -325,7 +330,8 @@ select
325330
f.program_activity_id,
326331
f.submission_id + {submission_id_shift}, -- to match submission shift
327332
f.treasury_account_id,
328-
f.disaster_emergency_fund_code
333+
f.disaster_emergency_fund_code,
334+
UPPER(CONCAT(piid, '|', parent_award_id, '|', fain, '|', uri))
329335
from
330336
financial_accounts_by_awards as f
331337
inner join submission_attributes as sa on sa.submission_id = f.submission_id

usaspending_api/database_scripts/job_archive/management/commands/generate_cares_act_test_data_sqls/copy_submissions.sql

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ insert into submission_attributes (
4343
update_date,
4444
reporting_agency_name,
4545
published_date,
46+
is_final_balances_for_fy,
47+
submission_window_id,
4648
_base_submission_id
4749
)
4850
select
@@ -65,6 +67,8 @@ select
6567
'{reporting_period_end}'::date + interval '1 days', -- update_date
6668
reporting_agency_name,
6769
'{reporting_period_end}'::date, -- published_date
70+
is_final_balances_for_fy,
71+
(SELECT id FROM dabs_submission_window_schedule dsws WHERE dsws.submission_fiscal_year = {destination_fiscal_year} AND dsws.submission_fiscal_month = {destination_fiscal_period} AND dsws.is_quarter = FALSE) AS submission_window_id,
6872
_base_submission_id
6973
from
7074
submission_attributes
@@ -284,7 +288,8 @@ insert into financial_accounts_by_awards (
284288
program_activity_id,
285289
submission_id,
286290
treasury_account_id,
287-
disaster_emergency_fund_code
291+
disaster_emergency_fund_code,
292+
distinct_award_key
288293
)
289294
select
290295
f.data_source,
@@ -334,7 +339,8 @@ select
334339
f.program_activity_id,
335340
sa._base_submission_id + {submission_id_shift}, -- to match submission shift
336341
f.treasury_account_id,
337-
f.disaster_emergency_fund_code
342+
f.disaster_emergency_fund_code,
343+
UPPER(CONCAT(piid, '|', parent_award_id, '|', fain, '|', uri))
338344
from
339345
financial_accounts_by_awards as f
340346
inner join submission_attributes as sa on sa.submission_id = f.submission_id
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import logging
2+
3+
from django.db import connection
4+
from django.core.management.base import BaseCommand
5+
6+
logger = logging.getLogger("script")
7+
8+
UPDATE_AWARDS_SQL = """
9+
WITH recent_covid_awards AS (
10+
SELECT
11+
DISTINCT ON
12+
(faba.award_id) faba.award_id,
13+
sa.is_final_balances_for_fy
14+
FROM
15+
financial_accounts_by_awards faba
16+
INNER JOIN disaster_emergency_fund_code defc ON
17+
defc.code = faba.disaster_emergency_fund_code
18+
AND defc.group_name = 'covid_19'
19+
INNER JOIN submission_attributes sa ON
20+
sa.reporting_period_start >= '2020-04-01'
21+
AND faba.submission_id = sa.submission_id
22+
INNER JOIN dabs_submission_window_schedule dabs ON
23+
dabs.id = sa.submission_window_id
24+
AND dabs.submission_reveal_date <= now()
25+
WHERE
26+
faba.award_id IS NOT NULL
27+
ORDER BY
28+
faba.award_id, submission_reveal_date DESC, is_quarter
29+
),
30+
last_periods_covid_awards AS (
31+
SELECT
32+
DISTINCT award_id
33+
FROM
34+
financial_accounts_by_awards faba
35+
INNER JOIN submission_attributes sa ON
36+
faba.submission_id = sa.submission_id
37+
INNER JOIN dabs_submission_window_schedule dabs ON
38+
dabs.id = sa.submission_window_id
39+
INNER JOIN disaster_emergency_fund_code defc ON
40+
defc.code = faba.disaster_emergency_fund_code
41+
AND defc.group_name = 'covid_19'
42+
WHERE
43+
(
44+
submission_fiscal_year = {last_months_year}
45+
AND submission_fiscal_month = {last_months_month}
46+
AND is_quarter = FALSE
47+
)
48+
OR (
49+
submission_fiscal_year = {last_quarters_year}
50+
AND submission_fiscal_month = {last_quarters_month}
51+
AND is_quarter = TRUE
52+
)
53+
)
54+
{operation_sql}
55+
WHERE
56+
id IN (
57+
SELECT
58+
*
59+
FROM
60+
last_periods_covid_awards
61+
)
62+
AND id IN (
63+
SELECT
64+
award_id
65+
FROM
66+
recent_covid_awards
67+
WHERE
68+
recent_covid_awards.is_final_balances_for_fy = FALSE
69+
)
70+
AND update_date < '{submission_reveal_date}'
71+
"""
72+
73+
UPDATE_AWARDS_ALL_SQL = """
74+
WITH covid_awards AS (
75+
SELECT
76+
DISTINCT ON
77+
(faba.award_id) faba.award_id,
78+
sa.is_final_balances_for_fy
79+
FROM
80+
financial_accounts_by_awards faba
81+
INNER JOIN disaster_emergency_fund_code defc ON
82+
defc.code = faba.disaster_emergency_fund_code
83+
AND defc.group_name = 'covid_19'
84+
INNER JOIN submission_attributes sa ON
85+
sa.reporting_period_start >= '2020-04-01'
86+
AND faba.submission_id = sa.submission_id
87+
INNER JOIN dabs_submission_window_schedule dabs ON
88+
dabs.id = sa.submission_window_id
89+
AND dabs.submission_reveal_date <= now()
90+
WHERE
91+
faba.award_id IS NOT NULL
92+
ORDER BY
93+
faba.award_id, submission_reveal_date DESC, is_quarter
94+
)
95+
{operation_sql}
96+
WHERE
97+
id IN (
98+
SELECT
99+
award_id
100+
FROM
101+
covid_awards
102+
WHERE
103+
covid_awards.is_final_balances_for_fy = FALSE
104+
)
105+
AND update_date < '{submission_reveal_date}'
106+
"""
107+
108+
RECENT_PERIOD_SQL = """
109+
SELECT
110+
submission_fiscal_month,
111+
submission_fiscal_year,
112+
is_quarter,
113+
submission_reveal_date
114+
FROM
115+
dabs_submission_window_schedule
116+
WHERE
117+
is_quarter = {is_quarter}
118+
AND submission_reveal_date < NOW()
119+
ORDER BY
120+
submission_fiscal_year DESC,
121+
submission_fiscal_month DESC
122+
LIMIT 2
123+
"""
124+
125+
UPDATE_OPERATION_SQL = """
126+
UPDATE
127+
awards
128+
SET
129+
update_date = NOW()
130+
"""
131+
132+
COUNT_OPERATION_SQL = """
133+
SELECT
134+
count(*)
135+
FROM
136+
awards AS award_to_update_count
137+
"""
138+
139+
140+
class Command(BaseCommand):
141+
"""
142+
NOTE: This command should be run on the `submission_reveal_date` of each period. This
143+
will ensure that covid values in elasticsearch are correctly each period. Running the
144+
command more frequently (ex. daily) will not result in values being constantly recalculated
145+
because an award's `updated_date` is compared against the `submission_reveal_date`
146+
when determining which awards to update.
147+
"""
148+
149+
help = (
150+
"This command sets the 'update_date' field on award records with Covid "
151+
"faba records present in a submission from the previous submission but "
152+
"not in the current period's submission."
153+
)
154+
155+
def add_arguments(self, parser):
156+
parser.add_argument(
157+
"--all",
158+
action="store_true",
159+
default=False,
160+
help="If this option is selected, ALL covid awards not present in the current period will be updated",
161+
)
162+
163+
parser.add_argument(
164+
"--dry-run",
165+
action="store_true",
166+
default=False,
167+
help="If this option is selected, awards will not be updated. The count of awards that would have been updated will instead be logged",
168+
)
169+
170+
def handle(self, *args, **options):
171+
periods = self.retreive_recent_periods()
172+
173+
submission_reveal_date = periods["this_month"]["submission_reveal_date"]
174+
dry_run = options["dry_run"]
175+
176+
operation_sql = UPDATE_OPERATION_SQL
177+
if dry_run:
178+
logger.info("Dry run flag provided. No records will be updated.")
179+
operation_sql = COUNT_OPERATION_SQL
180+
181+
if not options["all"]:
182+
formatted_update_sql = UPDATE_AWARDS_SQL.format(
183+
last_months_year=periods["last_month"]["year"],
184+
last_months_month=periods["last_month"]["month"],
185+
last_quarters_year=periods["last_quarter"]["year"],
186+
last_quarters_month=periods["last_quarter"]["month"],
187+
submission_reveal_date=submission_reveal_date,
188+
operation_sql=operation_sql,
189+
)
190+
else:
191+
logger.info("All flag provided. Updating all Covid awards not reported in the latest submission")
192+
formatted_update_sql = UPDATE_AWARDS_ALL_SQL.format(
193+
submission_reveal_date=submission_reveal_date, operation_sql=operation_sql
194+
)
195+
196+
self.execute_sql(formatted_update_sql, dry_run)
197+
198+
def retreive_recent_periods(self):
199+
# Open connection to database
200+
with connection.cursor() as cursor:
201+
202+
# Query for most recent closed month periods
203+
cursor.execute(RECENT_PERIOD_SQL.format(is_quarter="FALSE"))
204+
recent_month_periods = cursor.fetchmany(2)
205+
206+
# Query for most recent closed quarter periods
207+
cursor.execute(RECENT_PERIOD_SQL.format(is_quarter="TRUE"))
208+
recent_quarter_periods = cursor.fetchmany(2)
209+
210+
recent_periods = {
211+
"this_month": self.read_period_fields(recent_month_periods[0]),
212+
"last_month": self.read_period_fields(recent_month_periods[1]),
213+
"last_quarter": self.read_period_fields(recent_quarter_periods[1]),
214+
}
215+
216+
return recent_periods
217+
218+
def read_period_fields(self, period):
219+
return {"month": period[0], "year": period[1], "submission_reveal_date": period[3]}
220+
221+
def execute_sql(self, update_sql, dry_run):
222+
223+
# Open connection to database
224+
with connection.cursor() as cursor:
225+
cursor.execute(update_sql)
226+
227+
# Log results
228+
if dry_run:
229+
count = cursor.fetchone()[0]
230+
logger.info(
231+
f"There are {count:,} award records which should be reloaded into Elasticsearch for data consistency."
232+
)
233+
else:
234+
logger.info(f"Update message (records updated): {cursor.statusmessage}")

0 commit comments

Comments
 (0)