-
Notifications
You must be signed in to change notification settings - Fork 4
fix: expand actively_monitored_wells to include wells from all groups(BDMS-974/1178) #866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| """expand actively_monitored_wells to all groups | ||
|
|
||
| Drops the "WHERE group name = 'water level network'" restriction so the view | ||
| covers currently-monitored wells in any group, not just one. Public view | ||
| adds a group release_status = 'public' check instead, so draft/private | ||
| groups don't leak through now that any group can show up. Inner join to | ||
| group/group_thing_association is kept as-is (prod has no currently-monitored | ||
| well with zero group memberships); wells in multiple groups intentionally | ||
| appear once per group, no aggregation. | ||
|
|
||
| Revision ID: 986e0eb85ab3 | ||
| Revises: c3d4e5f6a7b8 | ||
| Create Date: 2026-08-20 10:55:25.697907 | ||
|
|
||
| """ | ||
|
|
||
| from typing import Sequence, Union | ||
|
|
||
| from alembic import op | ||
| from sqlalchemy import text | ||
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision: str = "986e0eb85ab3" | ||
| down_revision: Union[str, Sequence[str], None] = "c3d4e5f6a7b8" | ||
| branch_labels: Union[str, Sequence[str], None] = None | ||
| depends_on: Union[str, Sequence[str], None] = None | ||
|
|
||
|
|
||
| def _drop_view_or_materialized_view(view_name: str) -> None: | ||
| # DROP VIEW IF EXISTS / DROP MATERIALIZED VIEW IF EXISTS only suppress | ||
| # "relation does not exist" -- Postgres still raises WrongObjectType if | ||
| # the relation exists as the other kind, so the relation's actual kind | ||
| # must be checked first rather than trying both blindly. | ||
| bind = op.get_bind() | ||
| relkind = bind.execute( | ||
| text("SELECT relkind FROM pg_class WHERE oid = to_regclass(:name)"), | ||
| {"name": view_name}, | ||
| ).scalar() | ||
| if relkind == "m": | ||
| op.execute(text(f"DROP MATERIALIZED VIEW IF EXISTS {view_name}")) | ||
| elif relkind == "v": | ||
| op.execute(text(f"DROP VIEW IF EXISTS {view_name}")) | ||
|
|
||
|
|
||
| def _create_actively_monitored_wells_view(all_groups: bool) -> str: | ||
| # The all_groups branch drops the group-name predicate but still needs | ||
| # to keep draft/private groups off the public mount -- unlike the old | ||
| # single-group filter, any group can appear here now, so the group's own | ||
| # release_status has to be checked directly (mirrors | ||
| # _create_project_areas_view's public_only handling). | ||
| group_filter = ( | ||
| "g.release_status = 'public'\n AND " | ||
| if all_groups | ||
| else "lower(trim(g.name)) = 'water level network'\n AND " | ||
| ) | ||
| return f""" | ||
| CREATE VIEW ogc_actively_monitored_wells AS | ||
| WITH latest_monitoring_status AS ( | ||
| SELECT DISTINCT ON (sh.target_id) | ||
| sh.target_id AS thing_id, | ||
| sh.status_value | ||
| FROM status_history AS sh | ||
| WHERE | ||
| sh.target_table = 'thing' | ||
| AND sh.status_type = 'Monitoring Status' | ||
| ORDER BY sh.target_id, sh.start_date DESC, sh.id DESC | ||
| ) | ||
| SELECT | ||
| wws.id, | ||
| wws.name, | ||
|
Comment on lines
+69
to
+70
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jirhiker and @ksmuczynski
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @likithabommasani21 which do you prefer and why?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm leaning towards aggregation — it keeps id meaning "the well" everywhere and gives one API call the full picture of a well's group memberships instead of splitting it across duplicate rows. The one tradeoff: it changes the response shape - group_id become arrays instead of single values. If that's not a concern, I'd go with aggregation. If it is something we need to avoid, the alternative is a composite ID. But, worth noting that means id on this collection would no longer map back to the well's real id. |
||
| 'water well'::text AS thing_type, | ||
| wws.well_depth, | ||
| wws.elevation, | ||
| wws.elevation_method, | ||
| wws.formation_zone, | ||
| wws.total_water_levels, | ||
| wws.last_water_level, | ||
| wws.last_water_level_datetime, | ||
| wws.min_water_level, | ||
| wws.max_water_level, | ||
| wws.water_level_trend_ft_per_year, | ||
| g.id AS group_id, | ||
| g.name AS group_name, | ||
| g.group_type, | ||
| wws.point | ||
| FROM "group" AS g | ||
| JOIN group_thing_association AS gta ON gta.group_id = g.id | ||
| JOIN ogc_water_well_summary AS wws ON wws.id = gta.thing_id | ||
| JOIN latest_monitoring_status AS lms ON lms.thing_id = wws.id | ||
| WHERE {group_filter}lms.status_value = 'Currently monitored' | ||
| """ | ||
|
|
||
|
|
||
| def _create_internal_actively_monitored_wells_view(all_groups: bool) -> str: | ||
| group_filter = ( | ||
| "" | ||
| if all_groups | ||
| else "lower(trim(g.name)) = 'water level network'\n AND " | ||
| ) | ||
| return f""" | ||
| CREATE VIEW ogc_internal_actively_monitored_wells AS | ||
| WITH latest_monitoring_status AS ( | ||
| SELECT DISTINCT ON (sh.target_id) | ||
| sh.target_id AS thing_id, | ||
| sh.status_value | ||
| FROM status_history AS sh | ||
| WHERE | ||
| sh.target_table = 'thing' | ||
| AND sh.status_type = 'Monitoring Status' | ||
| ORDER BY sh.target_id, sh.start_date DESC, sh.id DESC | ||
| ) | ||
| SELECT | ||
| wws.id, | ||
| wws.name, | ||
| 'water well'::text AS thing_type, | ||
| wws.well_depth, | ||
| wws.elevation, | ||
| wws.elevation_method, | ||
| wws.formation_zone, | ||
| wws.total_water_levels, | ||
| wws.last_water_level, | ||
| wws.last_water_level_datetime, | ||
| wws.min_water_level, | ||
| wws.max_water_level, | ||
| wws.water_level_trend_ft_per_year, | ||
| g.id AS group_id, | ||
| g.name AS group_name, | ||
| g.group_type, | ||
| wws.point | ||
| FROM "group" AS g | ||
| JOIN group_thing_association AS gta ON gta.group_id = g.id | ||
| JOIN ogc_internal_water_well_summary AS wws ON wws.id = gta.thing_id | ||
| JOIN latest_monitoring_status AS lms ON lms.thing_id = wws.id | ||
| WHERE {group_filter}lms.status_value = 'Currently monitored' | ||
|
Comment on lines
+130
to
+134
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
| """ | ||
|
|
||
|
|
||
| def upgrade() -> None: | ||
| """Upgrade schema.""" | ||
| _drop_view_or_materialized_view("ogc_actively_monitored_wells") | ||
| op.execute(text(_create_actively_monitored_wells_view(all_groups=True))) | ||
| op.execute( | ||
| text( | ||
| "COMMENT ON VIEW ogc_actively_monitored_wells IS " | ||
| "'Actively (currently) monitored wells across all groups for pygeoapi.'" | ||
| ) | ||
| ) | ||
|
|
||
| _drop_view_or_materialized_view("ogc_internal_actively_monitored_wells") | ||
| op.execute(text(_create_internal_actively_monitored_wells_view(all_groups=True))) | ||
| op.execute( | ||
| text( | ||
| "COMMENT ON VIEW ogc_internal_actively_monitored_wells IS " | ||
| "'Actively (currently) monitored wells across all groups, " | ||
| "for the internal pygeoapi mount.'" | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| def downgrade() -> None: | ||
| """Downgrade schema.""" | ||
| _drop_view_or_materialized_view("ogc_actively_monitored_wells") | ||
| op.execute(text(_create_actively_monitored_wells_view(all_groups=False))) | ||
| op.execute( | ||
| text( | ||
| "COMMENT ON VIEW ogc_actively_monitored_wells IS " | ||
| "'Wells in the Water Level Network group for pygeoapi.'" | ||
| ) | ||
| ) | ||
|
|
||
| _drop_view_or_materialized_view("ogc_internal_actively_monitored_wells") | ||
| op.execute(text(_create_internal_actively_monitored_wells_view(all_groups=False))) | ||
| op.execute( | ||
| text( | ||
| "COMMENT ON VIEW ogc_internal_actively_monitored_wells IS " | ||
| "'Unfiltered wells in the Water Level Network group, " | ||
| "for the internal pygeoapi mount.'" | ||
| ) | ||
| ) | ||
Uh oh!
There was an error while loading. Please reload this page.