Exemple de migration de module
Note
Cet exemple illustre comment migrer d’un module Sterf déjà installé vers le module Sterf-eBMS, assurez-vous d’avoir lu cette section de la documentation avant de lire cette page.
Nous allons étudier ici un exemple de migration de module, plus précisement
depuis le module Sterf distribué sur le dépôt des parcs nationaux vers notre
module Sterf-eBMS. Dans cette page le nom de code du module Sterf actuel (aussi
désigné comme ancien module) est sterf, et le module Sterf-eBMS (ou nouveau
module) est sterf_ebms.
Cette migration nécessite d’avoir installé au préalable le module Sterf-eBMS de façon à avoir ses nomenclatures disponibles en base de données et vraisemblablement d’avoir bu un café ou deux. Ce document n’est pas un guide complet pas à pas mais essaye seulement d’accompagner votre démarche de migration.
Nous partons du principe que vous souhaitez automatiser au maximum la migration, mais il est toujours possible de procéder manuellement sur une partie ou toutes les entités que vous avez à migrer, par exemple recréer manuellement les différents transects et section dans le nouveau module, mais migrer en SQL les entités de visites et observations.
Avertissement
Cette page contient différents exemples de code SQL pour accompagner la migration. Il faut les adapter pour vos besoins, ne les exécutez pas sans avoir effectué une copie de votre base de données, et de préférence sur une instance de test clonée depuis votre production !
Migrations des transects
En parcourant le module Sterf, on peut noter les différences suivantes entre le format de ses données et celles attendues par le module Sterf-eBMS.
Le module Sterf ne comprend qu’un niveau géographique, les transects Sterf. Ces transects doivent être convertis en sections eBMS et il va falloir créer le niveau de groupe de site dans le module pour regrouper ces futures sections dans des transects eBMS.
Les habitats doivent être convertis.
Il manque à nos transects les attributs obligatoires suivants (on décide d’ignorer tous les attributs optionnels par simplicité) :
La largeur de transect ;
Le gestionnaire et la gestion du terrain.
Le module Sterf-eBMS ne possède pas l’attribut suivant :
« Modalité de sélection du site ».
Nouveau niveau géographique
Concernant le nouveau niveau géographique, on va ici partir du principe qu’on
peut créer un transect eBMS par transect Sterf, qui ne contiendra donc qu’une
seule section représentant notre transect Sterf. On peut copier le
sites_group.json du module Sterf-eBMS et l’épurer pour qu’il ne contienne
que les attributs qui nous importent.
Le code suivant va générer des groupes de sites à partir des transects associés
au module sterf.
-- Création des groupes de sites.
INSERT INTO gn_monitoring.t_sites_groups
(sites_group_name, sites_group_code, sites_group_description, uuid_sites_group, id_digitiser)
SELECT base_site_name, '', base_site_description, uuid_generate_v4(), id_digitiser
FROM gn_monitoring.t_base_sites tbs
JOIN gn_monitoring.cor_site_type cst USING (id_base_site)
JOIN gn_monitoring.cor_module_type cmt USING (id_type_site)
JOIN gn_commons.t_modules tm USING (id_module)
WHERE module_code = 'sterf';
-- Association des transects à leurs groupes de sites, en utilisant le fait
-- qu'ils aient le même nom (libre à vous de créer une liaison différente).
-- Attention ça ratisse large, on part du principe que tous les groupes de
-- sites créés dans la journée sont concernés par la migration.
UPDATE gn_monitoring.t_site_complements tsc
SET id_sites_group = sites.id_sites_group
FROM (
SELECT id_base_site, id_sites_group
FROM gn_monitoring.t_sites_groups tsg
JOIN gn_monitoring.t_base_sites tbs ON tbs.base_site_name = tsg.sites_group_name
WHERE EXTRACT(DAY FROM tsg.meta_create_date) = EXTRACT(DAY FROM NOW())
) sites
WHERE tsc.id_base_site = sites.id_base_site;
-- Association des nouveaux groupes de sites avec le module Sterf actuel.
-- Pareil, ça s'applique à tous les groupes de sites créés aujourd'hui.
INSERT INTO gn_monitoring.cor_sites_group_module
SELECT
id_sites_group,
gn_commons.get_id_module_bycode('sterf') AS id_module
FROM gn_monitoring.t_sites_groups
WHERE EXTRACT(DAY FROM meta_create_date) = EXTRACT(DAY FROM NOW());
À ce stade, le module n’affiche plus rien sur sa page d’accueil : en effet votre utilisateur n’a pas la permission d’afficher des groupes de sites pour ce module, car la permission n’existe pas encore, pour la bonne raison que GeoNature ne les a pas créé lors de l’installation du module, celui-ci n’ayant pas originellement de groupes de sites. Vous pouvez créer les permissions adéquates et les donner à votre groupe administrateur :
geonature monitorings update_module_available_permissions sterf
geonature permissions supergrant --group --nom "Grp_admin"
Planifier les migrations d’attributs
Les prochaines sections abordent la migration des attributs de vos transects Sterf vers les transects et sections eBMS. Avec ce nouveau niveau géographique, vous aurez peut-être à planifier à quel niveau doit être intégré tel ou tel attribut.
Par exemple dans le module actuel, on va vouloir migrer les attributs d’habitats. Dans le module Sterf-eBMS, ces attributs existent à la fois dans les transects et dans les sections, respectivement comme habitats à l’échelle de tout le site et comme habitats spécifiquement différent sur une section en particulier. Vu que l’on a choisi précédemment de créer un transect par section, un choix de migration possible est tout simplement de copier les infos d’habitat de la section vers son transect, et de conserver les attributs d’habitat de la section — ces attributs nécessitant tout de même une conversion, qui est le sujet de la prochaine section.
Habitats
Concernant les habitats, heureusement les deux modules se basent sur la nomenclature STOC et les données sont donc directement compatibles. Il faut seulement prendre en compte le changement de format : le module Sterf utilise des listes de sélection tandis que le module Sterf-eBMS utilise une nomenclature détaillée pour les habitats.
La conversion a pour principale complexité que les niveaux 2, 3 et 4 sont
dépendants du niveau 1, c’est à dire par exemple que la même valeur en niveau 2,
par exemple la lettre a, n’a pas la même signification selon si le premier
niveau est A (forêt, donc le niveau 2 signifie forêt de feuillus exclusifs)
ou E (milieux bâtis, donc le niveau 2 signifie zone urbaine résidentielle).
Dans l’exemple suivant, on prend le niveau d’habitat 1 du site, plus précisément
la première lettre de sa valeur, qui correspond à un code (une lettre de A à G),
et on le convertit en ID de nomenclature de type STERF_HAB_N1 correspondant,
c’est à dire la nomenclature d’habitat de niveau 1. Si par exemple le premier
niveau correspond à la valeur E, on va récupérer l’ID de la valeur
HAB1_E de la nomenclature.
UPDATE gn_monitoring.t_sites_groups tsg
SET "data" = COALESCE(tsg."data", jsonb_build_object()) || jsonb_build_object(
'habitat_main_1',
ref_nomenclatures.get_id_nomenclature(
'STERF_HAB_N1',
'HAB1_' || SUBSTRING(tsc.data->>'habitat_1' FROM 1 FOR 1)
)
)
FROM gn_monitoring.t_base_sites tbs
JOIN gn_monitoring.t_site_complements tsc USING (id_base_site)
WHERE
EXTRACT(DAY FROM meta_create_date) = EXTRACT(DAY FROM NOW())
AND tsg.id_sites_group = tsc.id_sites_group
AND tsc.data ? 'habitat_1'
Tout ceci est à adapter à la représentation des habitats de votre module, et il faut également prendre en compte les niveaux 2, 3 et 4 d’habitats. Pour représenter les habitats eBMS, le module Sterf-eBMS a besoin des deux premiers niveaux obligatoirement, les deux suivants sont optionnels mais conseillés.
Le code pour le niveau 2 des habitats, attachez vos ceintures :
-- On commence par récupérer les infos de nomenclatures d'habitats des deux
-- premiers niveaux, le niveau 2 dépendant du premier.
WITH
hab_n1 AS (
SELECT id_nomenclature, mnemonique
FROM ref_nomenclatures.t_nomenclatures
WHERE id_type = ref_nomenclatures.get_id_nomenclature_type('STERF_HAB_N1')
),
hab_n2 AS (
SELECT id_nomenclature, cd_nomenclature, label_default
FROM ref_nomenclatures.t_nomenclatures
WHERE id_type = ref_nomenclatures.get_id_nomenclature_type('STERF_HAB_N2')
)
UPDATE gn_monitoring.t_sites_groups tsg
SET "data" = tsg.data || jsonb_build_object('habitat_main_2', hab_n2.label_default)
FROM gn_monitoring.t_base_sites tbs
JOIN gn_monitoring.t_site_complements tsc USING (id_base_site)
JOIN gn_monitoring.t_sites_groups tsg_ USING (id_sites_group)
JOIN hab_n1
ON hab_n1.id_nomenclature = (tsg_.data->'habitat_main_1')::int
JOIN hab_n2
ON hab_n2.cd_nomenclature = CONCAT(
-- On reconstitue le code HAB2_x_y en fonction de X le niveau 1 et
-- Y le niveau 2. Il y a une subtilité : pour les niveaux 1 A et B,
-- les niveaux 2 sont les mêmes, donc il s'agit de la même
-- nomenclature pour les deux (HAB2_AB_y).
'HAB2_',
CASE hab_n1.mnemonique
WHEN 'A' THEN 'AB'
WHEN 'B' THEN 'AB'
ELSE hab_n1.mnemonique
END,
'_',
UPPER(SUBSTRING(tsc.data->>'habitat_2' FROM 1 FOR 1))
)
WHERE
EXTRACT(DAY FROM tsg.meta_create_date) = EXTRACT(DAY FROM NOW())
AND tsg.id_sites_group = tsc.id_sites_group
AND tsg.data ? 'habitat_main_1'
AND tsc.data ? 'habitat_2'
Les niveaux 3 et 4 suivent le même principe, à ceci près que le niveau 3 n’est pas sujet à la subtilité liée aux nomenclatures communes des types A et B de niveau 1, et sont laissés comme exercices pour le lecteur 😌.
Nouveaux attributs
Concernant les attributs à ajouter, heureusement ils possèdent tous une valeur
par défaut acceptable : la largeur de transect fait probablement 5 mètres, le
transect n’est probablement pas sensible, l’habitat secondaire est optionnel et
peut donc être ignoré. Les seuls attributs qu’il faudra impérativement remplir
sont le gestionnaire de terrain ainsi que la gestion de terrain, cependant les
deux nomenclatures acceptent une valeur par défaut qui peut servir en l’absence
d’information sur les transects, respectivement LT_UNKNOWN pour un
gestionnaire inconnu et LM_OTHER pour une gestion inconnue. Ces valeurs sont
à compléter avec des informations plus pertinentes quand c’est possible.
Il vous faudra également bien séparer les attributs des transects et les attributs des sections dans le cas où un nouveau niveau géographique est introduit.
Attributs manquants
Concernant les attributs manquants, il suffit d’ajouter votre attribut dans le module Sterf-eBMS.
Inclure ses transects dans le nouveau module
Jusqu’à présent le nouveau module n’affichera pas vos transects migrés car ceux-ci sont toujours rattachés à l’ancien module. Il va falloir inclure les transects (groupes de sites) dans le nouveau module, et changer le type de site pour utiliser celui du nouveau module.
-- On intègre nos transects dans le nouveau module.
-- Ils restent accessibles depuis l'ancien module.
INSERT INTO gn_monitoring.cor_sites_group_module
SELECT id_sites_group, gn_commons.get_id_module_bycode('sterf_ebms')
FROM gn_monitoring.t_sites_groups
JOIN gn_monitoring.cor_sites_group_module USING (id_sites_group)
WHERE id_module = gn_commons.get_id_module_bycode('sterf');
-- On change le type des sites de l'ancien module vers le nouveau.
UPDATE gn_monitoring.cor_site_type
SET id_type_site = ref_nomenclatures.get_id_nomenclature('TYPE_SITE', 'EBMS_SEC')
WHERE id_type_site = ref_nomenclatures.get_id_nomenclature('TYPE_SITE', 'STERF');
GeoNature permet qu’un groupe de sites soit utilisable par plusieurs modules, donc la première intégration ne les retire pas de l’ancien module. La seconde en revanche change le type des transects Sterf, par conséquent ils ne seront plus accessibles via l’ancien module tant que celui-ci ne sera pas reconfiguré pour utiliser les sites « Section eBMS », dans le formulaire d’édition de module.
Est-ce que mes attributs sont conservés après ces changements ?
Oui, vos attributs de sites (sections) et groupes de sites (transects) sont
conservés, dans les champs JSONB data respectivement des tables
t_site_complements et t_sites_groups. Une fois les modifications
précédentes effectuées, si vous modifiez votre site — anciennement transect
Sterf et désormais section eBMS — depuis le module Sterf-eBMS, les nouveaux
attributs sont ajoutés à l’objet JSON et les anciens attributs ne sont pas
supprimés. Vous pouvez donc envisager une migration progressive des
attributs, si vous êtes pris par le temps.
Migrations des visites et observations
Les visites sont en général plus simples à migrer vu qu’il n’y a aujourd’hui qu’un seul niveau de visite. La procédure consiste donc comme pour les transects et les sections à transférer les attributs de son module Sterf vers ceux du module Sterf-eBMS
Une fois cette étape terminée, les visites doivent être associées au nouveau module pour apparaitre lors de la consultation du site.
UPDATE gn_monitoring.t_base_visits
SET id_module = gn_commons.get_id_module_bycode('sterf_ebms')
WHERE id_module = gn_commons.get_id_module_bycode('sterf');
Les observations ne nécessitent pas de traitement particulier, à part la transformation des attributs, mais à ce stade vous avez l’habitude !