-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Issue #1363] Update the Opportunity summary database models based on…
… updated database schema plan (#1402) ## Summary Fixes #1363 ### Time to review: __10 mins__ ## Changes proposed Updated the DB models for the opportunity tables Update the factories to handle creating a current opportunity summary in a few scenarios Temporarily disable some validations in the API tests (To be fixed in #1364 ) ## Context for reviewers https://app.gitbook.com/o/cFcvhi6d0nlLyH2VzVgn/s/v1V0jIH7mb7Yb3jlNrgk/engineering/learnings/opportunity-endpoint-data-model#overview provides most of the details regarding the updated schema, but in short, opportunity summary was adjusted to have its own primary key and allow for multiple opportunity summaries per opportunity - as well as some shuffling of fields. There are two migrations in this PR, one to first delete the opportunity summary table, and the other to add/modify all of the other tables. Because we changed the primary key and how the connections between the tables work, Alembic couldn't automatically detect the changes necessary for creating the tables. While this could be modified manually, it ends up much cleaner / simpler to just drop and remake the table entirely instead. Non-locally we've not populated these tables so this has no impact. ## Additional information Running the `db-seed-local` script generates data locally as expected: ![Screenshot 2024-03-05 at 1 50 00 PM](https://github.com/HHS/simpler-grants-gov/assets/46358556/fd104e3b-39d8-4987-83d5-03227cc4f819) In the current table, only 25 records are created as 5 opportunities have no summary: ![Screenshot 2024-03-05 at 1 50 57 PM](https://github.com/HHS/simpler-grants-gov/assets/46358556/97d0521c-c978-4480-b93b-9b8a2567bc28) The factories generate the opportunity summary with varying information, setting certain fields depending on the scenario (eg. only setting forecasted fields for forecasts): ![Screenshot 2024-03-05 at 1 51 59 PM](https://github.com/HHS/simpler-grants-gov/assets/46358556/b8c8bf92-924b-4128-98f7-aa8d61773e6e) --------- Co-authored-by: nava-platform-bot <platform-admins@navapbc.com>
- Loading branch information
1 parent
5ab44c2
commit f72d63b
Showing
7 changed files
with
971 additions
and
119 deletions.
There are no files selected for viewing
299 changes: 299 additions & 0 deletions
299
api/src/db/migrations/versions/2024_03_07_drop_tables_to_remake.py
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,299 @@ | ||
"""Drop tables to remake | ||
Revision ID: ac80e949bcf8 | ||
Revises: 5d58c38f2cac | ||
Create Date: 2024-03-07 10:20:15.639825 | ||
""" | ||
import sqlalchemy as sa | ||
from alembic import op | ||
from sqlalchemy.dialects import postgresql | ||
|
||
# revision identifiers, used by Alembic. | ||
revision = "ac80e949bcf8" | ||
down_revision = "5d58c38f2cac" | ||
branch_labels = None | ||
depends_on = None | ||
|
||
|
||
def upgrade(): | ||
# ### commands auto generated by Alembic - please adjust! ### | ||
op.drop_table("link_funding_instrument_opportunity") | ||
op.drop_index("opportunity_is_draft_idx", table_name="opportunity") | ||
op.drop_index("opportunity_opportunity_category_id_idx", table_name="opportunity") | ||
op.drop_index("opportunity_opportunity_title_idx", table_name="opportunity") | ||
|
||
op.drop_table("link_funding_category_opportunity") | ||
op.drop_table("link_applicant_type_opportunity") | ||
op.drop_index( | ||
"opportunity_assistance_listing_opportunity_id_idx", | ||
table_name="opportunity_assistance_listing", | ||
) | ||
op.drop_table("opportunity_assistance_listing") | ||
op.drop_table("opportunity_summary") | ||
op.drop_table("opportunity") | ||
# ### end Alembic commands ### | ||
|
||
|
||
def downgrade(): | ||
# ### commands auto generated by Alembic - please adjust! ### | ||
op.create_table( | ||
"opportunity", | ||
sa.Column( | ||
"opportunity_id", | ||
sa.INTEGER(), | ||
server_default=sa.text("nextval('opportunity_opportunity_id_seq'::regclass)"), | ||
autoincrement=True, | ||
nullable=False, | ||
), | ||
sa.Column("opportunity_number", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("opportunity_title", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("agency", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("is_draft", sa.BOOLEAN(), autoincrement=False, nullable=False), | ||
sa.Column( | ||
"created_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.Column( | ||
"updated_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.Column("category_explanation", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("revision_number", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column("modified_comments", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("publisher_user_id", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column("publisher_profile_id", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column("opportunity_category_id", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.ForeignKeyConstraint( | ||
["opportunity_category_id"], | ||
["lk_opportunity_category.opportunity_category_id"], | ||
name="opportunity_opportunity_category_id_lk_opportunity_cate_c6e9", | ||
), | ||
sa.PrimaryKeyConstraint("opportunity_id", name="opportunity_pkey"), | ||
postgresql_ignore_search_path=False, | ||
) | ||
op.create_index( | ||
"opportunity_opportunity_title_idx", "opportunity", ["opportunity_title"], unique=False | ||
) | ||
op.create_index( | ||
"opportunity_opportunity_category_id_idx", | ||
"opportunity", | ||
["opportunity_category_id"], | ||
unique=False, | ||
) | ||
op.create_index("opportunity_is_draft_idx", "opportunity", ["is_draft"], unique=False) | ||
op.create_table( | ||
"opportunity_summary", | ||
sa.Column("opportunity_id", sa.INTEGER(), autoincrement=False, nullable=False), | ||
sa.Column("opportunity_status_id", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column("summary_description", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("is_cost_sharing", sa.BOOLEAN(), autoincrement=False, nullable=True), | ||
sa.Column("close_date", sa.DATE(), autoincrement=False, nullable=True), | ||
sa.Column("close_date_description", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("post_date", sa.DATE(), autoincrement=False, nullable=True), | ||
sa.Column("archive_date", sa.DATE(), autoincrement=False, nullable=True), | ||
sa.Column("unarchive_date", sa.DATE(), autoincrement=False, nullable=True), | ||
sa.Column("expected_number_of_awards", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column( | ||
"estimated_total_program_funding", sa.INTEGER(), autoincrement=False, nullable=True | ||
), | ||
sa.Column("award_floor", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column("award_ceiling", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column("additional_info_url", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("additional_info_url_description", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("version_number", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column("modification_comments", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("funding_category_description", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column( | ||
"applicant_eligibility_description", sa.TEXT(), autoincrement=False, nullable=True | ||
), | ||
sa.Column("agency_code", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("agency_name", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("agency_phone_number", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("agency_contact_description", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("agency_email_address", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column( | ||
"agency_email_address_description", sa.TEXT(), autoincrement=False, nullable=True | ||
), | ||
sa.Column("can_send_mail", sa.BOOLEAN(), autoincrement=False, nullable=True), | ||
sa.Column("publisher_profile_id", sa.INTEGER(), autoincrement=False, nullable=True), | ||
sa.Column("publisher_user_id", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("updated_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("created_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column( | ||
"created_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.Column( | ||
"updated_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.ForeignKeyConstraint( | ||
["opportunity_id"], | ||
["opportunity.opportunity_id"], | ||
name="opportunity_summary_opportunity_id_opportunity_fkey", | ||
), | ||
sa.ForeignKeyConstraint( | ||
["opportunity_status_id"], | ||
["lk_opportunity_status.opportunity_status_id"], | ||
name="opportunity_summary_opportunity_status_id_lk_opportunit_ea00", | ||
), | ||
sa.PrimaryKeyConstraint("opportunity_id", name="opportunity_summary_pkey"), | ||
) | ||
op.create_table( | ||
"opportunity_assistance_listing", | ||
sa.Column( | ||
"opportunity_assistance_listing_id", sa.INTEGER(), autoincrement=True, nullable=False | ||
), | ||
sa.Column("opportunity_id", sa.INTEGER(), autoincrement=False, nullable=False), | ||
sa.Column("program_title", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("assistance_listing_number", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("updated_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("created_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column( | ||
"created_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.Column( | ||
"updated_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.ForeignKeyConstraint( | ||
["opportunity_id"], | ||
["opportunity.opportunity_id"], | ||
name="opportunity_assistance_listing_opportunity_id_opportunity_fkey", | ||
), | ||
sa.PrimaryKeyConstraint( | ||
"opportunity_assistance_listing_id", name="opportunity_assistance_listing_pkey" | ||
), | ||
) | ||
op.create_index( | ||
"opportunity_assistance_listing_opportunity_id_idx", | ||
"opportunity_assistance_listing", | ||
["opportunity_id"], | ||
unique=False, | ||
) | ||
op.create_table( | ||
"link_applicant_type_opportunity", | ||
sa.Column("opportunity_id", sa.INTEGER(), autoincrement=False, nullable=False), | ||
sa.Column("applicant_type_id", sa.INTEGER(), autoincrement=False, nullable=False), | ||
sa.Column("updated_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("created_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column( | ||
"created_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.Column( | ||
"updated_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.ForeignKeyConstraint( | ||
["applicant_type_id"], | ||
["lk_applicant_type.applicant_type_id"], | ||
name="link_applicant_type_opportunity_applicant_type_id_lk_ap_7903", | ||
), | ||
sa.ForeignKeyConstraint( | ||
["opportunity_id"], | ||
["opportunity.opportunity_id"], | ||
name="link_applicant_type_opportunity_opportunity_id_opportunity_fkey", | ||
), | ||
sa.PrimaryKeyConstraint( | ||
"opportunity_id", "applicant_type_id", name="link_applicant_type_opportunity_pkey" | ||
), | ||
) | ||
op.create_table( | ||
"link_funding_category_opportunity", | ||
sa.Column("opportunity_id", sa.INTEGER(), autoincrement=False, nullable=False), | ||
sa.Column("funding_category_id", sa.INTEGER(), autoincrement=False, nullable=False), | ||
sa.Column("updated_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("created_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column( | ||
"created_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.Column( | ||
"updated_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.ForeignKeyConstraint( | ||
["funding_category_id"], | ||
["lk_funding_category.funding_category_id"], | ||
name="link_funding_category_opportunity_funding_category_id_l_4add", | ||
), | ||
sa.ForeignKeyConstraint( | ||
["opportunity_id"], | ||
["opportunity.opportunity_id"], | ||
name="link_funding_category_opportunity_opportunity_id_opport_eb65", | ||
), | ||
sa.PrimaryKeyConstraint( | ||
"opportunity_id", "funding_category_id", name="link_funding_category_opportunity_pkey" | ||
), | ||
) | ||
|
||
op.create_table( | ||
"link_funding_instrument_opportunity", | ||
sa.Column("opportunity_id", sa.INTEGER(), autoincrement=False, nullable=False), | ||
sa.Column("funding_instrument_id", sa.INTEGER(), autoincrement=False, nullable=False), | ||
sa.Column("updated_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column("created_by", sa.TEXT(), autoincrement=False, nullable=True), | ||
sa.Column( | ||
"created_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.Column( | ||
"updated_at", | ||
postgresql.TIMESTAMP(timezone=True), | ||
server_default=sa.text("now()"), | ||
autoincrement=False, | ||
nullable=False, | ||
), | ||
sa.ForeignKeyConstraint( | ||
["funding_instrument_id"], | ||
["lk_funding_instrument.funding_instrument_id"], | ||
name="link_funding_instrument_opportunity_funding_instrument__68d6", | ||
), | ||
sa.ForeignKeyConstraint( | ||
["opportunity_id"], | ||
["opportunity.opportunity_id"], | ||
name="link_funding_instrument_opportunity_opportunity_id_oppo_9420", | ||
), | ||
sa.PrimaryKeyConstraint( | ||
"opportunity_id", | ||
"funding_instrument_id", | ||
name="link_funding_instrument_opportunity_pkey", | ||
), | ||
) | ||
# ### end Alembic commands ### |
Oops, something went wrong.