From a9602f0ce76ea4f271801f88c14e511a3b64e427 Mon Sep 17 00:00:00 2001 From: Julien Maupetit Date: Thu, 16 Jan 2025 16:27:09 +0100 Subject: [PATCH] add alembic migration --- ...d15436b0_add_statique_materialized_view.py | 39 +++++++++++++++++++ src/api/qualicharge/schemas/core.py | 16 +++++--- 2 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 src/api/qualicharge/migrations/versions/4b99d15436b0_add_statique_materialized_view.py diff --git a/src/api/qualicharge/migrations/versions/4b99d15436b0_add_statique_materialized_view.py b/src/api/qualicharge/migrations/versions/4b99d15436b0_add_statique_materialized_view.py new file mode 100644 index 00000000..a07a9d9c --- /dev/null +++ b/src/api/qualicharge/migrations/versions/4b99d15436b0_add_statique_materialized_view.py @@ -0,0 +1,39 @@ +"""Add statique materialized view + +Revision ID: 4b99d15436b0 +Revises: d3d2c20f8efd +Create Date: 2025-01-16 15:02:04.004411 + +""" + +from typing import Sequence, Union + +from alembic import op +from sqlalchemy_utils.view import CreateView, DropView + +from qualicharge.schemas.core import _StatiqueMV + +# revision identifiers, used by Alembic. +revision: str = "4b99d15436b0" +down_revision: Union[str, None] = "d3d2c20f8efd" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Create the Statique Materialized view and related indexes.""" + op.execute( + CreateView( + _StatiqueMV.__table__.fullname, _StatiqueMV.selectable, materialized=True + ) + ) + for idx in _StatiqueMV.__table__.indexes: + idx.create(op.get_bind()) + + +def downgrade() -> None: + """Delete the Statique Materialized View.""" + + op.execute( + DropView(_StatiqueMV.__table__.fullname, materialized=True, cascade=True) + ) diff --git a/src/api/qualicharge/schemas/core.py b/src/api/qualicharge/schemas/core.py index 3b7d9801..2b2b7c6e 100644 --- a/src/api/qualicharge/schemas/core.py +++ b/src/api/qualicharge/schemas/core.py @@ -1,7 +1,7 @@ """QualiCharge core statique and dynamique schemas.""" from enum import IntEnum -from typing import TYPE_CHECKING, List, Optional, Union, cast +from typing import TYPE_CHECKING, ClassVar, List, Optional, Union, cast from uuid import UUID, uuid4 from geoalchemy2.functions import ST_AsGeoJSON @@ -20,7 +20,7 @@ ) from pydantic_extra_types.coordinate import Coordinate from shapely.geometry import mapping -from sqlalchemy import event +from sqlalchemy import Select, event from sqlalchemy.orm import registry from sqlalchemy.schema import Column as SAColumn from sqlalchemy.schema import Index @@ -415,9 +415,8 @@ class _StatiqueMV(SQLModel): NOTE: This is an internal model used **ONLY** for creating the materialized view. """ - __table__ = create_materialized_view( - name=STATIQUE_MV_TABLE_NAME, - selectable=select( + selectable: ClassVar[Select] = ( + select( # FIXME # Should be the Enum value PointDeCharge.accessibilite_pmr, @@ -473,7 +472,12 @@ class _StatiqueMV(SQLModel): .join(Amenageur, Station.amenageur_id == Amenageur.id) .join(Operateur, Station.operateur_id == Operateur.id) .join(Enseigne, Station.enseigne_id == Enseigne.id) - .join(Localisation, Station.localisation_id == Localisation.id), + .join(Localisation, Station.localisation_id == Localisation.id) + ) + + __table__ = create_materialized_view( + name=STATIQUE_MV_TABLE_NAME, + selectable=selectable, metadata=SQLModel.metadata, indexes=[ Index("idx_statique_id_pdc_itinerance", "id_pdc_itinerance", unique=True),