Skip to content

Commit

Permalink
[MONITORING - site]
Browse files Browse the repository at this point in the history
- db and model evolution to make site cross module
- some fixes on GN2CommonModule forms
  • Loading branch information
amandine-sahl authored and TheoLechemia committed Aug 19, 2024
1 parent 3adc7b4 commit 6928098
Show file tree
Hide file tree
Showing 12 changed files with 566 additions and 46 deletions.
98 changes: 83 additions & 15 deletions backend/geonature/core/gn_monitoring/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from geoalchemy2 import Geometry
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.sql import select, func


Expand All @@ -16,12 +16,13 @@
from utils_flask_sqla.serializers import serializable
from utils_flask_sqla_geo.serializers import geoserializable

from pypnnomenclature.models import TNomenclatures
from geonature.core.gn_commons.models import TModules
from geonature.core.gn_meta.models import TDatasets
from geonature.utils.env import DB


corVisitObserver = DB.Table(
cor_visit_observer = DB.Table(
"cor_visit_observer",
DB.Column(
"id_base_visit",
Expand All @@ -39,7 +40,7 @@
)


corSiteModule = DB.Table(
cor_site_module = DB.Table(
"cor_site_module",
DB.Column(
"id_base_site",
Expand All @@ -56,7 +57,7 @@
schema="gn_monitoring",
)

corSiteArea = DB.Table(
cor_site_area = DB.Table(
"cor_site_area",
DB.Column(
"id_base_site",
Expand All @@ -68,6 +69,58 @@
schema="gn_monitoring",
)

cor_module_type = DB.Table(
"cor_module_type",
DB.Column(
"id_module",
DB.Integer,
DB.ForeignKey("gn_commons.t_modules.id_module"),
primary_key=True,
),
DB.Column(
"id_type_site",
DB.Integer,
DB.ForeignKey("gn_monitoring.bib_type_site.id_nomenclature_type_site"),
primary_key=True,
),
schema="gn_monitoring",
)

cor_site_type = DB.Table(
"cor_site_type",
DB.Column(
"id_base_site",
DB.Integer,
DB.ForeignKey("gn_monitoring.t_base_sites.id_base_site"),
primary_key=True,
),
DB.Column(
"id_type_site",
DB.Integer,
DB.ForeignKey("gn_monitoring.bib_type_site.id_nomenclature_type_site"),
primary_key=True,
),
schema="gn_monitoring",
)


@serializable
class BibTypeSite(DB.Model):
__tablename__ = "bib_type_site"
__table_args__ = {"schema": "gn_monitoring"}

id_nomenclature_type_site = DB.Column(
DB.ForeignKey("ref_nomenclatures.t_nomenclatures.id_nomenclature"),
nullable=False,
primary_key=True,
)
config = DB.Column(JSONB)
nomenclature = DB.relationship(
TNomenclatures, uselist=False, backref=DB.backref("bib_type_site", uselist=False)
)

sites = DB.relationship("TBaseSites", secondary=cor_site_type, lazy="noload")


@serializable
class TBaseVisits(DB.Model):
Expand All @@ -84,7 +137,7 @@ class TBaseVisits(DB.Model):
# Pour le moment non défini comme une clé étrangère
# pour les questions de perfs
# a voir en fonction des usage
id_module = DB.Column(DB.Integer)
id_module = DB.Column(DB.Integer, ForeignKey("gn_commons.t_modules.id_module"))

visit_date_min = DB.Column(DB.DateTime)
visit_date_max = DB.Column(DB.DateTime)
Expand All @@ -102,15 +155,16 @@ class TBaseVisits(DB.Model):

observers = DB.relationship(
User,
secondary=corVisitObserver,
primaryjoin=(corVisitObserver.c.id_base_visit == id_base_visit),
secondaryjoin=(corVisitObserver.c.id_role == User.id_role),
foreign_keys=[corVisitObserver.c.id_base_visit, corVisitObserver.c.id_role],
secondary=cor_visit_observer,
primaryjoin=(cor_visit_observer.c.id_base_visit == id_base_visit),
secondaryjoin=(cor_visit_observer.c.id_role == User.id_role),
foreign_keys=[cor_visit_observer.c.id_base_visit, cor_visit_observer.c.id_role],
)

observers_txt = DB.Column(DB.Unicode)

dataset = relationship(
TDatasets,
lazy="joined",
primaryjoin=(TDatasets.id_dataset == id_dataset),
foreign_keys=[id_dataset],
)
Expand All @@ -128,7 +182,6 @@ class TBaseSites(DB.Model):
id_base_site = DB.Column(DB.Integer, primary_key=True)
id_inventor = DB.Column(DB.Integer, ForeignKey("utilisateurs.t_roles.id_role"))
id_digitiser = DB.Column(DB.Integer, ForeignKey("utilisateurs.t_roles.id_role"))
id_nomenclature_type_site = DB.Column(DB.Integer)
base_site_name = DB.Column(DB.Unicode)
base_site_description = DB.Column(DB.Unicode)
base_site_code = DB.Column(DB.Unicode)
Expand All @@ -153,8 +206,23 @@ class TBaseSites(DB.Model):
"TModules",
lazy="select",
enable_typechecks=False,
secondary=corSiteModule,
primaryjoin=(corSiteModule.c.id_base_site == id_base_site),
secondaryjoin=(corSiteModule.c.id_module == TModules.id_module),
foreign_keys=[corSiteModule.c.id_base_site, corSiteModule.c.id_module],
secondary=cor_site_module,
primaryjoin=(cor_site_module.c.id_base_site == id_base_site),
secondaryjoin=(cor_site_module.c.id_module == TModules.id_module),
foreign_keys=[cor_site_module.c.id_base_site, cor_site_module.c.id_module],
)


@serializable
class TObservations(DB.Model):
__tablename__ = "t_observations"
__table_args__ = {"schema": "gn_monitoring"}
id_observation = DB.Column(DB.Integer, primary_key=True, nullable=False, unique=True)
id_base_visit = DB.Column(DB.ForeignKey("gn_monitoring.t_base_visits.id_base_visit"))
id_digitiser = DB.Column(DB.Integer, DB.ForeignKey("utilisateurs.t_roles.id_role"))
digitiser = DB.relationship(
User, primaryjoin=(User.id_role == id_digitiser), foreign_keys=[id_digitiser]
)
cd_nom = DB.Column(DB.Integer)
comments = DB.Column(DB.String)
uuid_observation = DB.Column(UUID(as_uuid=True), default=select(func.uuid_generate_v4()))
12 changes: 6 additions & 6 deletions backend/geonature/core/gn_monitoring/routes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from flask import Blueprint, request
from geojson import FeatureCollection
from geonature.core.gn_monitoring.models import TBaseSites, corSiteArea, corSiteModule
from geonature.core.gn_monitoring.models import TBaseSites, cor_site_area, cor_site_module
from geonature.utils.env import DB
from ref_geo.models import LAreas
from sqlalchemy import select
Expand Down Expand Up @@ -79,16 +79,16 @@ def get_site_areas(id_site):
params = request.args

query = (
select(corSiteArea, func.ST_Transform(LAreas.geom, 4326))
.join(LAreas, LAreas.id_area == corSiteArea.c.id_area)
.where(corSiteArea.c.id_base_site == id_site)
select(cor_site_area, func.ST_Transform(LAreas.geom, 4326))
.join(LAreas, LAreas.id_area == cor_site_area.c.id_area)
.where(cor_site_area.c.id_base_site == id_site)
)

if "id_area_type" in params:
query = query.where(LAreas.id_type == params["id_area_type"])
if "id_module" in params:
query = query.join(corSiteModule, corSiteModule.c.id_base_site == id_site).where(
corSiteModule.c.id_module == params["id_module"]
query = query.join(cor_site_module, cor_site_module.c.id_base_site == id_site).where(
cor_site_module.c.id_module == params["id_module"]
)

data = DB.session.scalars(query).all()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""add sensitivity filter export synthese
Revision ID: 5a2c9c65129f
Revises: 446e902a14e7
Revises: d99a7c22cc3c
Create Date: 2023-08-08 16:23:53.059110
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""[monitoring] add id_digitizer to t_observations
Revision ID: 6734d8f7eb2a
Revises: 9b88459c1298
Create Date: 2024-01-16 15:50:30.308266
"""

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "6734d8f7eb2a"
down_revision = "9b88459c1298"
branch_labels = None
depends_on = None


monitorings_schema = "gn_monitoring"
table = "t_observations"
column = "id_digitiser"

foreign_schema = "utilisateurs"
table_foreign = "t_roles"
foreign_key = "id_role"


def upgrade():
op.add_column(
table,
sa.Column(
column,
sa.Integer(),
sa.ForeignKey(
f"{foreign_schema}.{table_foreign}.{foreign_key}",
name=f"fk_{table}_{column}",
onupdate="CASCADE",
),
),
schema=monitorings_schema,
)
op.execute(
"""
UPDATE gn_monitoring.t_observations o SET id_digitiser = tbv.id_digitiser
FROM gn_monitoring.t_base_visits AS tbv
WHERE tbv.id_base_visit = o.id_base_visit;
"""
)
# Set not null constraint
op.alter_column(
table_name=table,
column_name=column,
existing_type=sa.Integer(),
nullable=False,
schema=monitorings_schema,
)


def downgrade():
statement = sa.text(
f"""
ALTER TABLE {monitorings_schema}.{table} DROP CONSTRAINT fk_{table}_{column};
"""
)
op.execute(statement)
op.drop_column(table, column, schema=monitorings_schema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""[monitoring] add_observers_txt_column_t_base_visit
Revision ID: 8309591841f3
Revises: 5a2c9c65129f
Create Date: 2023-10-06 11:07:43.532623
"""

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "8309591841f3"
down_revision = "ebbe0f7ed866"
branch_labels = None
depends_on = None


monitorings_schema = "gn_monitoring"
table = "t_base_visits"
column = "observers_txt"


def upgrade():
op.add_column(
table,
sa.Column(
column,
sa.Text(),
nullable=True,
),
schema=monitorings_schema,
)


def downgrade():
op.drop_column(table, column, schema=monitorings_schema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""[monitoring] create t_observations
Revision ID: 9b88459c1298
Revises: a54bafb13ce8
Create Date: 2024-01-16 15:41:13.331912
"""

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "9b88459c1298"
down_revision = "a54bafb13ce8"
branch_labels = None
depends_on = None


def upgrade():
op.execute(
"""
CREATE TABLE IF NOT EXISTS gn_monitoring.t_observations (
id_observation SERIAL NOT NULL,
id_base_visit INTEGER NOT NULL,
cd_nom INTEGER NOT NULL,
comments TEXT,
uuid_observation UUID DEFAULT uuid_generate_v4() NOT NULL,
CONSTRAINT pk_t_observations PRIMARY KEY (id_observation),
CONSTRAINT fk_t_observations_id_base_visit FOREIGN KEY (id_base_visit)
REFERENCES gn_monitoring.t_base_visits (id_base_visit) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
);
"""
)
op.execute(
"""
INSERT INTO gn_commons.bib_tables_location(table_desc, schema_name, table_name, pk_field, uuid_field_name)
VALUES
('Table centralisant les observations réalisées lors d''une visite sur un site', 'gn_monitoring', 't_observations', 'id_observation', 'uuid_observation')
ON CONFLICT(schema_name, table_name) DO NOTHING;
"""
)


def downgrade():
op.execute(
"""
DELETE FROM gn_commons.bib_tables_location
WHERE schema_name = 'gn_monitoring' AND table_name = 't_observations';
"""
)
op.drop_table("t_observations", schema="gn_monitoring")
Loading

0 comments on commit 6928098

Please sign in to comment.