Skip to content

Commit 62db49e

Browse files
amandine-sahljacquesfize
authored andcommitted
[MONITORING - site]
- db and model evolution to make site cross module - some fixes on GN2CommonModule forms
1 parent 14f5801 commit 62db49e

13 files changed

+567
-46
lines changed

backend/geonature/core/gn_monitoring/models.py

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from geoalchemy2 import Geometry
88
from sqlalchemy import ForeignKey
99
from sqlalchemy.orm import relationship
10-
from sqlalchemy.dialects.postgresql import UUID
10+
from sqlalchemy.dialects.postgresql import UUID, JSONB
1111
from sqlalchemy.sql import select, func
1212

1313

@@ -16,12 +16,13 @@
1616
from utils_flask_sqla.serializers import serializable
1717
from utils_flask_sqla_geo.serializers import geoserializable
1818

19+
from pypnnomenclature.models import TNomenclatures
1920
from geonature.core.gn_commons.models import TModules
2021
from geonature.core.gn_meta.models import TDatasets
2122
from geonature.utils.env import DB
2223

2324

24-
corVisitObserver = DB.Table(
25+
cor_visit_observer = DB.Table(
2526
"cor_visit_observer",
2627
DB.Column(
2728
"id_base_visit",
@@ -39,7 +40,7 @@
3940
)
4041

4142

42-
corSiteModule = DB.Table(
43+
cor_site_module = DB.Table(
4344
"cor_site_module",
4445
DB.Column(
4546
"id_base_site",
@@ -56,7 +57,7 @@
5657
schema="gn_monitoring",
5758
)
5859

59-
corSiteArea = DB.Table(
60+
cor_site_area = DB.Table(
6061
"cor_site_area",
6162
DB.Column(
6263
"id_base_site",
@@ -68,6 +69,58 @@
6869
schema="gn_monitoring",
6970
)
7071

72+
cor_module_type = DB.Table(
73+
"cor_module_type",
74+
DB.Column(
75+
"id_module",
76+
DB.Integer,
77+
DB.ForeignKey("gn_commons.t_modules.id_module"),
78+
primary_key=True,
79+
),
80+
DB.Column(
81+
"id_type_site",
82+
DB.Integer,
83+
DB.ForeignKey("gn_monitoring.bib_type_site.id_nomenclature_type_site"),
84+
primary_key=True,
85+
),
86+
schema="gn_monitoring",
87+
)
88+
89+
cor_site_type = DB.Table(
90+
"cor_site_type",
91+
DB.Column(
92+
"id_base_site",
93+
DB.Integer,
94+
DB.ForeignKey("gn_monitoring.t_base_sites.id_base_site"),
95+
primary_key=True,
96+
),
97+
DB.Column(
98+
"id_type_site",
99+
DB.Integer,
100+
DB.ForeignKey("gn_monitoring.bib_type_site.id_nomenclature_type_site"),
101+
primary_key=True,
102+
),
103+
schema="gn_monitoring",
104+
)
105+
106+
107+
@serializable
108+
class BibTypeSite(DB.Model):
109+
__tablename__ = "bib_type_site"
110+
__table_args__ = {"schema": "gn_monitoring"}
111+
112+
id_nomenclature_type_site = DB.Column(
113+
DB.ForeignKey("ref_nomenclatures.t_nomenclatures.id_nomenclature"),
114+
nullable=False,
115+
primary_key=True,
116+
)
117+
config = DB.Column(JSONB)
118+
nomenclature = DB.relationship(
119+
TNomenclatures, uselist=False, backref=DB.backref("bib_type_site", uselist=False)
120+
)
121+
122+
sites = DB.relationship("TBaseSites", secondary=cor_site_type, lazy="noload")
123+
71124

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

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

103156
observers = DB.relationship(
104157
User,
105-
secondary=corVisitObserver,
106-
primaryjoin=(corVisitObserver.c.id_base_visit == id_base_visit),
107-
secondaryjoin=(corVisitObserver.c.id_role == User.id_role),
108-
foreign_keys=[corVisitObserver.c.id_base_visit, corVisitObserver.c.id_role],
158+
secondary=cor_visit_observer,
159+
primaryjoin=(cor_visit_observer.c.id_base_visit == id_base_visit),
160+
secondaryjoin=(cor_visit_observer.c.id_role == User.id_role),
161+
foreign_keys=[cor_visit_observer.c.id_base_visit, cor_visit_observer.c.id_role],
109162
)
110163

164+
observers_txt = DB.Column(DB.Unicode)
165+
111166
dataset = relationship(
112167
TDatasets,
113-
lazy="joined",
114168
primaryjoin=(TDatasets.id_dataset == id_dataset),
115169
foreign_keys=[id_dataset],
116170
)
@@ -128,7 +182,6 @@ class TBaseSites(DB.Model):
128182
id_base_site = DB.Column(DB.Integer, primary_key=True)
129183
id_inventor = DB.Column(DB.Integer, ForeignKey("utilisateurs.t_roles.id_role"))
130184
id_digitiser = DB.Column(DB.Integer, ForeignKey("utilisateurs.t_roles.id_role"))
131-
id_nomenclature_type_site = DB.Column(DB.Integer)
132185
base_site_name = DB.Column(DB.Unicode)
133186
base_site_description = DB.Column(DB.Unicode)
134187
base_site_code = DB.Column(DB.Unicode)
@@ -153,8 +206,23 @@ class TBaseSites(DB.Model):
153206
"TModules",
154207
lazy="select",
155208
enable_typechecks=False,
156-
secondary=corSiteModule,
157-
primaryjoin=(corSiteModule.c.id_base_site == id_base_site),
158-
secondaryjoin=(corSiteModule.c.id_module == TModules.id_module),
159-
foreign_keys=[corSiteModule.c.id_base_site, corSiteModule.c.id_module],
209+
secondary=cor_site_module,
210+
primaryjoin=(cor_site_module.c.id_base_site == id_base_site),
211+
secondaryjoin=(cor_site_module.c.id_module == TModules.id_module),
212+
foreign_keys=[cor_site_module.c.id_base_site, cor_site_module.c.id_module],
213+
)
214+
215+
216+
@serializable
217+
class TObservations(DB.Model):
218+
__tablename__ = "t_observations"
219+
__table_args__ = {"schema": "gn_monitoring"}
220+
id_observation = DB.Column(DB.Integer, primary_key=True, nullable=False, unique=True)
221+
id_base_visit = DB.Column(DB.ForeignKey("gn_monitoring.t_base_visits.id_base_visit"))
222+
id_digitiser = DB.Column(DB.Integer, DB.ForeignKey("utilisateurs.t_roles.id_role"))
223+
digitiser = DB.relationship(
224+
User, primaryjoin=(User.id_role == id_digitiser), foreign_keys=[id_digitiser]
160225
)
226+
cd_nom = DB.Column(DB.Integer)
227+
comments = DB.Column(DB.String)
228+
uuid_observation = DB.Column(UUID(as_uuid=True), default=select(func.uuid_generate_v4()))

backend/geonature/core/gn_monitoring/routes.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from flask import Blueprint, request
22
from geojson import FeatureCollection
3-
from geonature.core.gn_monitoring.models import TBaseSites, corSiteArea, corSiteModule
3+
from geonature.core.gn_monitoring.models import TBaseSites, cor_site_area, cor_site_module
44
from geonature.utils.env import DB
55
from ref_geo.models import LAreas
66
from sqlalchemy import select
@@ -79,16 +79,16 @@ def get_site_areas(id_site):
7979
params = request.args
8080

8181
query = (
82-
select(corSiteArea, func.ST_Transform(LAreas.geom, 4326))
83-
.join(LAreas, LAreas.id_area == corSiteArea.c.id_area)
84-
.where(corSiteArea.c.id_base_site == id_site)
82+
select(cor_site_area, func.ST_Transform(LAreas.geom, 4326))
83+
.join(LAreas, LAreas.id_area == cor_site_area.c.id_area)
84+
.where(cor_site_area.c.id_base_site == id_site)
8585
)
8686

8787
if "id_area_type" in params:
8888
query = query.where(LAreas.id_type == params["id_area_type"])
8989
if "id_module" in params:
90-
query = query.join(corSiteModule, corSiteModule.c.id_base_site == id_site).where(
91-
corSiteModule.c.id_module == params["id_module"]
90+
query = query.join(cor_site_module, cor_site_module.c.id_base_site == id_site).where(
91+
cor_site_module.c.id_module == params["id_module"]
9292
)
9393

9494
data = DB.session.scalars(query).all()

backend/geonature/migrations/versions/5a2c9c65129f_add_sensitivity_filter_export_synthese.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""add sensitivity filter export synthese
22
33
Revision ID: 5a2c9c65129f
4-
Revises: 446e902a14e7
4+
Revises: d99a7c22cc3c
55
Create Date: 2023-08-08 16:23:53.059110
66
77
"""
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""[monitoring] add id_digitizer to t_observations
2+
3+
Revision ID: 6734d8f7eb2a
4+
Revises: 9b88459c1298
5+
Create Date: 2024-01-16 15:50:30.308266
6+
7+
"""
8+
9+
from alembic import op
10+
import sqlalchemy as sa
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = "6734d8f7eb2a"
15+
down_revision = "9b88459c1298"
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
monitorings_schema = "gn_monitoring"
21+
table = "t_observations"
22+
column = "id_digitiser"
23+
24+
foreign_schema = "utilisateurs"
25+
table_foreign = "t_roles"
26+
foreign_key = "id_role"
27+
28+
29+
def upgrade():
30+
op.add_column(
31+
table,
32+
sa.Column(
33+
column,
34+
sa.Integer(),
35+
sa.ForeignKey(
36+
f"{foreign_schema}.{table_foreign}.{foreign_key}",
37+
name=f"fk_{table}_{column}",
38+
onupdate="CASCADE",
39+
),
40+
),
41+
schema=monitorings_schema,
42+
)
43+
op.execute(
44+
"""
45+
UPDATE gn_monitoring.t_observations o SET id_digitiser = tbv.id_digitiser
46+
FROM gn_monitoring.t_base_visits AS tbv
47+
WHERE tbv.id_base_visit = o.id_base_visit;
48+
"""
49+
)
50+
# Set not null constraint
51+
op.alter_column(
52+
table_name=table,
53+
column_name=column,
54+
existing_type=sa.Integer(),
55+
nullable=False,
56+
schema=monitorings_schema,
57+
)
58+
59+
60+
def downgrade():
61+
statement = sa.text(
62+
f"""
63+
ALTER TABLE {monitorings_schema}.{table} DROP CONSTRAINT fk_{table}_{column};
64+
"""
65+
)
66+
op.execute(statement)
67+
op.drop_column(table, column, schema=monitorings_schema)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""[monitoring] add_observers_txt_column_t_base_visit
2+
3+
Revision ID: 8309591841f3
4+
Revises: 5a2c9c65129f
5+
Create Date: 2023-10-06 11:07:43.532623
6+
7+
"""
8+
9+
from alembic import op
10+
import sqlalchemy as sa
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = "8309591841f3"
15+
down_revision = "ebbe0f7ed866"
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
monitorings_schema = "gn_monitoring"
21+
table = "t_base_visits"
22+
column = "observers_txt"
23+
24+
25+
def upgrade():
26+
op.add_column(
27+
table,
28+
sa.Column(
29+
column,
30+
sa.Text(),
31+
nullable=True,
32+
),
33+
schema=monitorings_schema,
34+
)
35+
36+
37+
def downgrade():
38+
op.drop_column(table, column, schema=monitorings_schema)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""[monitoring] create t_observations
2+
3+
Revision ID: 9b88459c1298
4+
Revises: a54bafb13ce8
5+
Create Date: 2024-01-16 15:41:13.331912
6+
7+
"""
8+
9+
from alembic import op
10+
import sqlalchemy as sa
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = "9b88459c1298"
15+
down_revision = "a54bafb13ce8"
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
op.execute(
22+
"""
23+
CREATE TABLE IF NOT EXISTS gn_monitoring.t_observations (
24+
id_observation SERIAL NOT NULL,
25+
id_base_visit INTEGER NOT NULL,
26+
cd_nom INTEGER NOT NULL,
27+
comments TEXT,
28+
uuid_observation UUID DEFAULT uuid_generate_v4() NOT NULL,
29+
30+
31+
CONSTRAINT pk_t_observations PRIMARY KEY (id_observation),
32+
CONSTRAINT fk_t_observations_id_base_visit FOREIGN KEY (id_base_visit)
33+
REFERENCES gn_monitoring.t_base_visits (id_base_visit) MATCH SIMPLE
34+
ON UPDATE CASCADE ON DELETE CASCADE
35+
);
36+
"""
37+
)
38+
op.execute(
39+
"""
40+
INSERT INTO gn_commons.bib_tables_location(table_desc, schema_name, table_name, pk_field, uuid_field_name)
41+
VALUES
42+
('Table centralisant les observations réalisées lors d''une visite sur un site', 'gn_monitoring', 't_observations', 'id_observation', 'uuid_observation')
43+
ON CONFLICT(schema_name, table_name) DO NOTHING;
44+
"""
45+
)
46+
47+
48+
def downgrade():
49+
op.execute(
50+
"""
51+
DELETE FROM gn_commons.bib_tables_location
52+
WHERE schema_name = 'gn_monitoring' AND table_name = 't_observations';
53+
"""
54+
)
55+
op.drop_table("t_observations", schema="gn_monitoring")

0 commit comments

Comments
 (0)