Skip to content
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

Multiples instances / Réplications #789

Closed
orovellotti opened this issue Nov 7, 2019 · 11 comments
Closed

Multiples instances / Réplications #789

orovellotti opened this issue Nov 7, 2019 · 11 comments

Comments

@orovellotti
Copy link

orovellotti commented Nov 7, 2019

Quel est votre position sur les réplications entre instances?

La région pays de Loire a une instance qu’elle veut faire communiquer avec une instance d’un Pnr local.

Nous pourrions utiliser un ETL, une réplication partielle de bases à bases, ou du code python dédié ?

Merci

@orovellotti orovellotti changed the title Multiple instance/replication. Multiples instances / Réplications Nov 7, 2019
@gildeluermoz
Copy link
Contributor

gildeluermoz commented Nov 7, 2019

Je dirais code dédié via les API.
Les ETL pitié non. On y a goûté c'est terrible à maintenir.
La réplication je connais mal mais ça pose des questions de droits à partager et je me demande pourquoi répliquer quand on peut ouvrir une base en lecture à qui ont veut et comme on veut.

En fait tout ça dépend du besoin et de l'organisation souhaitée (1 base centrale et des filles, des bases réparties sans maître ?, autre ?)
Le principe du moissonnage des métadonnées me semble bon. Il s'appuie sur le standard et via une API documentée tu peux moissonner ce qui est disponible dans une base ouverte (ou via authentification préalable). On pourrait s'appuyer sur le standard d'occurrence de taxon et sur celui des métadonnées.
A étudier, les évolutions, notamment en synthèse, pour savoir comment garer des occurrences ainsi moissonnées.

@DonovanMaillard
Copy link
Contributor

Ne comprenant pas tout je ne sais pas si c'est en lien mais pour éviter qu'un boulot soit fait en double. On a commencé avec Fred à la lpo le développement de scripts permettant de moissonner données et méta-données dans une instance mère pour alimenter une instance fille (basé sur les api des modules exports et méta-données)

Ces développements devraient se pour suivre au cours de l'hiver... Je sais pas si ça vous intéresse ou non pour ce sujet ;) désolé d'avance si ça n'a rien à voir

@lpofredc
Copy link
Contributor

lpofredc commented Nov 8, 2019

Oui, je confirme, c'est prévu pour 2020. L'objectif serait de s'appuyer sur le module d'export pour générer des api permettant le partage entre instances geonature. Voici ce qui est envisagé:

Côté fournisseur de données :

Ajouter une fonction de journalisation sur la synthèse de GeoNature permettant de suivre l’historique des modifications des données naturalistes de la synthèse (insertion, mise à jour, suppression).
Pour chaque export « partenaire », 3 à 4 flux web seront générés :

  • Le journal des modifications (date, id_données, action > ajout, modification, suppression, champs possiblement objets d’un filtrage pour générer l’export partenaire (groupe taxonomique, cadre d’acquisition, etc) ;
  • Les données ;
  • Les métadonnées (Cadres d’acquisition et jeux de données) ;
  • Les organismes (intégrés aux métadonnées ?).

Côté collecteur de données:

Côté serveur, un premier téléchargement en mode complet (pour télécharger toutes les données de l’export) puis une mise à jour incrémentale régulière (horaire, quotidienne) ne récupérant que les données ayant subit une modification depuis le dernier export (insertion, modification, suppression).

Côté base de données:

  • l’enregistrement en base de données d’un journal des imports permettant de définir le point de départ de la mise à jour incrémentale.
  • Des déclencheurs automatiques sur la table de réception des données permettant l’alimentation automatique de la synthèse GeoNature (et des métadonnées ?).

@lpofredc
Copy link
Contributor

lpofredc commented Apr 9, 2020

Je reviens vers vous tous pour avancer sur ce chantier et vous propose un premier jet de réflexion sur ce que pourrait être cet outil, à discuter ensemble. en fin de ticket un schéma récapitulatif...

Objectif

L’objectif de cet outils est de permettra le reversement automatique de données entre instances geonature et par api. L’émetteur fournit des données filtrées par API, le collecteur réceptionne les données de l’API émetteur et les intègre en base de données via une interface qui fait le lien entre les deux.

image

Les données à communiquer entre instances

Données naturalistes

  • Données de synthèses formatées avec les nomenclatures associées (cd_nomenclature?), que faire des nomenclatures custom ?

Les métadonnées

  • sources (gn_synthese.t_sources) ?
  • Cadres d’acquisitions
  • Jeux de données
  • Organismes associés aux métadonnées ?

Historique des données

  • Une journalisation des des données permettant la mise en place de mises à jour incrémentales (ne récupérer que les données nouvelles, mises à jour et effacer les données supprimées).

Autres données ?

  • Les données d’habitats ?

Ce qui existe aujourd’hui dans Geonature

Données naturalistes

  • Synthèse, exporter les données avec les cd_nomenclatures.
  • Fonctions postgresql pour associer les données attributaires des nomenclatures, a voir en termes de performances par rapport à des jointures avec une vue dédiée.

Métadonnées

  • Cadre d’acquisition : Donnée standard avec UUID
  • Jeux de données : Donnée standard avec UUID
  • Organismes associés : Donnée (standard?) avec UUID. Risque de redondance avec des organismes déjà existants mais aux UUID différents ?

Historique des données

La journalisation des modifications sur les données est enregistré dans la table gn_commons.t_history_actions. Il concerne les sources de données suivantes , donc aucune des tables qui nous intéressent pour cette application

Schéma table
gn_commons t_medias
gn_monitoring t_base_sites
gn_monitoring t_base_visits
pr_occtax cor_counting_occtax
pr_occtax t_occurrences_occtax
pr_occtax t_releves_occtax
pr_occtax cor_role_releves_occtax
pr_occhab t_habitats
pr_occhab t_stations

Les outils actuellement disponibles

Module d’export

génère des api d’après des vues créées en base de données, l’accès aux api peut être restreint pour des utilisateurs/groupes enregistrés dans usershub ou pubiques.

Les API générées disposent de capacités de filtrages (querystring) et de pagination.

Module d’import

Importe des données tabulaires (csv) via des masques paramétrés (par défaut, synthèse geonature).

Interface entre les instances

Pas de solutions existantes à ce jour. La LPO Auvergne-Rhône-Alpes utilise une application accomplissant le même type de tâches pour importer et mettre à jour en continue les données des portails VisioNature vers une base de données PostgreSQL (https://framagit.org/lpo/Client_API_VN/) dont le fonctionnement est proche de ce qui est attendu ici. Une partie de l'application pourrait-être utilisée.

Le processus envisagé

Cet outil s’appuierait sur le module d’export et une application à développer qui ferait l’interface entre les deux instances de GeoNature.

Côté collecteur

Ce fonctionnement nécessite l’ajout d’une journalisation sur les tables (INSERT, UPDATE, DELETE) :

  • gn_synthese.synthese
  • gn_meta.t_acquisition_frameworks
  • gn_meta.t_datasets
  • utilisateurs.bib_organism

Les étapes réalisées seraient :

  1. Générer une vue standardisée d’après la synthèse pour une transmission vers un autre geonature (quelle préférence pour les nomenclatures : cd_nomenclatures ?).
  2. Cette vue est alors intégrée dans le module d’export dans lequel une case « export standard pour instance géonature » pourrait être cochée.
  3. Si l’option « export standard pour instance géonature » est activée, alors 5 vues supplémentaires seraient générées et diffusée par le modcollecteurule d’export avec les mêmes droits que la synthèse configurée :
  • Un dictionnaire des API (une vue simple qui listera les URL des 5 URL nécessaires), à renseignée dans l’interface.
  • Le Journal des modifications (« diff »)
  • Les données des organismes associés aux métadonnées des données sélectionnées
  • Les données des cadres d’acquisition & des jeux de données associés aux données sélectionnés
  • Les données de synthèse

Côté interface

L’interface serait une application Python (sans doute autonome dans un premier temps, possiblement intégrable en module dans un second temps) qui assurera le butinage sur les différentes sources renseignées.

Pour chaque source, il faudrait spécifier l’URL du dictionnaire des URL du partage, et les paramètres d’authentification (identifiant, mot de passe).

Deux modes seront disponibles :

  • Full, à éxécuter au premier chargement d’une source et dans l’ordre suivant de manière à respecter la cohérence des données :

    1. organismes
    2. cadres d’acquisition
    3. jeux de données
    4. données de synthèse
  • Update, à éxécuter pour mettre à jour les données d’après les données fournies par le journal des modifications et à réaliser dans le même ordre que précédemment.

Côté collecteur

Les données sont intégrées dans un schéma spécifique (ex : import_geonature) dans 4 tables correspondant aux 4 types de données, soit au format JSONB plus souple mais plus lourd, soit en colonnes avec en plus une colonne spécifiant la source de la donnée.

1. organismes
2. cadres d’acquisition
3. jeux de données
4. données de synthèse

Des déclencheurs d’évènements surveillent ces tables pour mettre à jour les tables de GeoNature respectives.

Premières questions en suspens

  • Comment gérer des imports avec des taxons « nouveaux » provenant d’une source ayant un taxref plus récent ?
  • Comment gérer les mises à jours des métadonnées (cadres d’acquisition, jeux de données et organismes associés) ?
  • Comment prioriser les données si donnée redondante entre bases (meta_create/meta_update (propre à chaque intance)) ?

image

@DonovanMaillard
Copy link
Contributor

Salut Fred,

Sans trop rentrer dans le détail dans l'immédiat, penses-tu repartir des premiers travaux qu'on a entamés l'an dernier ou reprendre les choses depuis la base? Je vois que c'est très proche de ce qu'on avait entamé mais tu n'en as pas parlé.

De manière générale pour les taxons nouveaux, pour les nomenclatures personnalisées etc, j'aurais tendance à fonctionner avec quelque chose du style "ON CONFLICT DO NOTHING" de manière à ignorer les cas particuliers, qui seraient récupérés ultérieurement (on peut imaginer un rapport d'erreur dans les logs du script pour avoir connaissance de ces cas là coté serveur dans un premier temps). Ca peut aussi concerner des nomenclatures supprimées dans la base collecteur ou autres cas.

Coté nomenclature, une pratique prévue consiste à créer des nomenclatures custom mais à les rattacher à des nomenclatures "officielles" via le champs id_broader. Ca permet de créer des nomenclatures filles précises et adaptées pour des besoins internes mais de faciliter la transformation vers le standard en identifiant la nomenclature valide qui correspond. Il peut etre intéressant, quand un cd_nomenclature est customisé, de voir s'il a un broader valide du SINP.

Coté métadonnées, il serait intéressant de se baser sur l'API du module métadonnée de la base émetteur. La t_source ne me semble pas pertinente à prendre en compte dans ce fonctionnement en revanche, elle est surtout technique finalement et concerne l'instance en elle-même (table d'origine, champs source de la pk etc), qui ne sert pas si on a pas la donnée source dans la base collecteur.

Coté organismes, l'idéal serait en effet, à terme, que chacun puisse avec UsersHub aller importer des organismes qui sont dans le référentiel SINP... mais ça soulève plein de soucis (usershub n'est pas destiné qu'à GeoNature ni qu'au contexte sinp).
En attendant, à part générer des doublons à gérer au cas par cas, je ne vois pas de solution... c'est en tous cas la mauvaise solution conservée dans le script d'import des métadonnées de l'INPN que j'avais fait et qui ne devrait pas servir d'exemple, mais pas mieux pour l'instant.

Sur la manière de mettre à jour des métadonnées, je la verrais comme pour les données avec une mise à jour fréquente. En revanche il n'est peut être pas nécessaire d'historiser toutes les actions : ca représente un volume de données assez faible, on peut peut être prévoir un update complet Peut êtr- avec une fréquence inférieure à celle des données, en dehors des cas où un nouveau jeu de données doit être importé qui se fait d'office ?

Sur la priorisation des informations : je pense que selon les cas et les pratiques des uns et des autres, ça peut différer. J'imagine qu'un paramètre dans la configuration du script pourrait permettre à l'utilisateur de choisir son fonctionnement (j'importe les dates de l'émetteur, ou je mets les miennes). Ou alors imaginer un 3eme champs date, pour le rafraichissement de la donnée (indépendant de sa création et sa mise à jour qui sont différents).

Je rajoute une question : qui de l'id_digitiser.

D'un point de vue technique, il faudrait aussi anticiper, ou au moins documenter, le fait que l'import "full" initial va potentiellement bloquer du fait des triggers et autres intersections de la base collecteur. Soit automatiser le bloquage du trigger cor_area_synthese puis relancer la commande ensuite, soit au moins signaler ce point là dans la doc pour que l'utilisateur puisse anticiper.

@camillemonchicourt
Copy link
Member

OK intéressant et merci pour ce gros récap !

Avant toute chose, je pense qu'il faut garder en tête qu'on peut aussi avoir des échanges de données entre instances GeoNature de manière plus simple, dans certains cas.
Par exemple, si je récupère les données d'un partenaire, je ne suis pas forcément intéressé pour intégré tout le détail de ses nombreux JDD, qui ne m'apporteront pas forcément mais complexifieraient beaucoup ma BDD, mes filtres par JDD etc.... Je peux préférer mettre ça dans un JDD unique "Convention Partenaire X" et que ce JDD soit unique et défini dans l'import de l'API. De la même manière quand je vais remonter mes données PNE à des partenaires ou au SINP, tout le détail complexe et souvent interne de mes JDD n'a pas vocation forcément à remonter tel quel au partenaire ou au SINP.
Dans ce cas là, un JDD local spécifique pour un flux API sera préférable à un échange de JDD complexe, un mapping des organismes etc...

Donc les 2 mécanismes doivent pouvoir cohabiter et on peut déjà réfléchir au cas simple où 1 API =
1 JDD défini au niveau du collecteur.
Je commencerai par faire fonctionner ça, avant de voir pour les JDD, les organismes etc...


Pour les sources, clairement c'est un référentiel local qui n'a pas vocation à être partagé.

Je ne pense pas que le concept de "export standard pour instance GeoNature" soit vraiment pertinent. En effet dans mon GeoNature, je peux avoir différents exports (correspondant à différents exports) qui alimentent des GeoNature différents et de manière différent.
Mais on peut en effet imaginer que pour certains export on veut pouvoir activer les API associées (journal, métadonnées...). Quoique on peut aussi mettre en place automatiquement ce mécanisme pour toutes les API et l'utiliser ou non au niveau du collecteur. Car si on met en place une API c'est pour y brancher un outil tiers, donc le journal peut servir, les métadonnées aussi etc.. Pas uniquement entre 2 GeoNature. Donc je généraliserai le fait d'avoir des API associées à chaque API de données.

Je pense aussi que si une valeur n'est pas reconnue dans la BDD du collecteur (taxon, cd_nomenclature...), alors elle est ignorée, idéalement loguée.
Pour ce qui concerne les contrôles des erreurs, les rapports d'erreurs... il y a certainement des choses à utiliser existantes dans le module d'Import.

Concernant la priorisation des données, dans un échange de données il doit y avoir une base maître et une base esclave. Y en a qu'une qui écrase l'autre en cas de différente.

Je ne suis pas sur de voir pourquoi il faut faire 2 modes. L'import initial est le même que les suivants sauf qu'il est plus long et qu'il n'y a rien à mettre à jour, que des nouveautés. Mais c'est le même mécanique et le même processus.

@camillemonchicourt
Copy link
Member

Travail initié dans https://github.com/lpoaura/gn2gn_client/tree/dev

@lpofredc
Copy link
Contributor

Je viens de publier une première pre-release avec la fonctionnalité de base permettant de rapatrier les données d'un export dans une base de données, stockées dans un champ JSON. Il s'agit d'une application Python exécutée depuis en ligne de commande (programmable avec un cron).

Dépot: https://github.com/lpoaura/gn2gn_client
Docs: https://gn2gn-client.readthedocs.io/en/latest/
Docker: https://hub.docker.com/r/lpoaura/gn2gn-client

Il reste principalement à développer :

Sélection_012

Sélection_013

@Adrien-Pajot
Copy link
Contributor

Bonjour @lpofredc ,

Dans le cadre de la mission COBIODIV SI je vais essayer le développement effectué.
Une petite remarque, les liens https://gn2gn-client.readthedocs.io/en/latest/ et https://hub.docker.com/r/lpoaura/gn2gn-client ne me mènent à rien, c'est que pour moi ? J'espère les retrouver dans le répo !

Merci pour ce travail !

@lpofredc
Copy link
Contributor

lpofredc commented Mar 1, 2021

Bonjour @Adrien-Pajot,

L'application a été renommée depuis en GN2PG (cf. lpoaura/GN2PG#5).
Les bonnes url sont:

NB: La partie incrémentale n'est toujours pas finalisée.

@lpofredc lpofredc mentioned this issue Aug 26, 2021
@camillemonchicourt camillemonchicourt added this to the 2.12 milestone Feb 13, 2023
@bouttier bouttier removed this from the 2.12 milestone Mar 1, 2023
@camillemonchicourt
Copy link
Member

L'historisation des suppressions dans la Synthèse et l'API associée a été intégrée dans la version 2.12.0.
Elle est nécessaire à l'utilisation de GN2PG.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants