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

Feature/taxonomie-dependency #321

Merged
merged 70 commits into from
Dec 21, 2021
Merged

Conversation

mvergez
Copy link

@mvergez mvergez commented Nov 24, 2021

Main Goal

Remove taxonomy scheme dependency

This PR enables also to

  • Remove ref_geo scheme dependency
  • Split each service to a docker-compose service (frontend, backend, database)
  • Make the installation easier

Closes #236, #216, #167

lpofredc and others added 8 commits October 5, 2021 23:41
Add backend + db in docker-compose
Removed imports relative to Taxhub
Removed queries relative to Taxhub: TODO
Add get_all_lists function
Removed calls to taxonomy models
Removed taxonomy models
Removed check on TaxHub Api
Replaced by an API call to get the municipality from a latitude
and a longitude. Called each time an observation is added.
Make this URL a parameter in the configuration
Updated the front to get only the name of the municipality
In the DataBase the municipality is the name of the town/city
Mount the media volume to persist photos provided by the users
Add db persistence
@camillemonchicourt
Copy link
Member

On part sur une installation obligatoire avec Docker ?

@mvergez
Copy link
Author

mvergez commented Nov 24, 2021

Non on laissera le choix aux deux. On s'attaque au script d'installation en fin de semaine normalement.

Cette PR est peut-être mal nommée, elle consiste avant tout à casser les dépendances au schéma taxonomie. On en profite pour dockeriser pour que ce soit plus simple à tester sur un environnement vierge.

N'hésite pas si tu as besoin de plus d'informations

@mvergez mvergez changed the title Feature/docker Feature/taxonomie-dependency Nov 24, 2021
@camillemonchicourt
Copy link
Member

OK super, merci pour les précisions

Maxime Vergez added 18 commits November 25, 2021 09:01
Added try/except to catch errors in get_municipality function to
prevent new observation from being created.
The main encountered error is a DNS error caused by WSL + Docker
apparently. Solved by restarting docker service. For this to never
happen, this call can be done in the frontend part and the city
can be sent to the backend
Add call to Taxhub/Taxref to get families and class
In config: changed API parameter name
Since there can be problems in calling nominatim (API_CITY) in the
backend. It is now also called in the frontend with the same
API_CITY parameter in the app.config.
The API_CITY is called in the backend if the frontend does not
manage to get a city (municipality)
Add nginx service as well as the required configuration
Before: everything was in media which requires to copy assets into
medias directory
Now: Front loads images in assets or asks the backend to get an
image from the medias directory
Add scripts that are used both in docker.sh and install_app.sh
Normally it should automatically install docker as well as
docker-compose and launch the app
To be coherent with install_app, the htpasswd file should be in
the config and named backoffice_htpasswd
Did a function to loop on cd_nom but since we only need one cd_nom
we do not need this function anymore
Took what is in the dev branch
Consist in building the backend, the frontend and the nginx images
Add corresponding docker-compose file
Add Dockerfile for nginx to copy the configuration
Add dockerignore file to reduce context
Maxime Vergez added 2 commits December 7, 2021 14:53
sql migration: add the name column (taxon name) + change
municipality column type to varchar

python: script to populate columns name and municipality by
respectively the taxon name (from taxhub) and the municipality
name (from nominatim)
@mvergez
Copy link
Author

mvergez commented Dec 7, 2021

Penser aux scripts SQL de montée en version.

Fait dans le commit 8a7d0e6
Composé :

  • d'un script de migration sql pour ajouter une nouvelle colonne (nom du taxon) et modifier le type d'une autre (municipalité) dans t_obstax
  • d'un script Python qui remplit ces deux colonnes avec des appels aux API taxhub et nominatim respectivement

@camillemonchicourt
Copy link
Member

J'avoue que là sur les histoires d'ajout de colonne "nom" et "communes", nominatim etc, je ne comprends pas du tout le sujet.
Je croyais que cette PR concernait uniquement le script d'installation en même temps que la suppression de la dépendance au schéma taxonomie, pour passer par l'API de TaxHub.

Si il y a d'autres choses, à bien indiquer dans le Changelog (docs/CHANGELOG.md) dans la PR.
Et notamment si il y a des commandes particulières à exécuter (python ou SQL) lors de la mise à jour pour ceux qui ont la version précédente.

Dans tous les cas, sans avoir trop compris de quoi il s'agit, je pense que ce n'est pas vraiment souhaitable de stocker dans la table des observations le nom du taxon en plus du cd_nom. C'est une info redondante et si Taxref évolue, on aura dupliqué une info qui peut avoir changé dans Taxref.
Concernant le fait de stocker une commune dans les observations, idem, c'est dommage il me semble, surtout en utilisant "nominatim" qui n'est pas toujours très juste.

@mvergez
Copy link
Author

mvergez commented Dec 8, 2021

Effectivement c'était l'objectif de cette PR : supprimer le schéma taxref de la base de données et faciliter l'installation.

Mais dans ce processus, nous avons eu l'idée de faire la même chose avec le ref_geo : pourquoi avoir un ref_geo alors qu'une API est disponible pour permettre de localiser (même si parfois moins précisément) une observation ?
Nous étions partis sur https://geo.api.gouv.fr/ mais @lpofredc a justement fait remarquer que citizen était déjà à l'international donc il valait mieux passer par Nominatim (par exemple).

Pour les scripts de migration, ils sont fournis avec et seront documentés.

Je comprends totalement ta remarque sur le stockage du nom en plus du cd_nom qui crée une redondance. C'était une demande de @samuelpriou. Mais faire un appel à l'API de taxhub dans le backoffice pour toutes les observations à chaque fois (même avec un système puissant de caching) ne me parait pas très optimisé. Relancer le script fourni (data/migrations/add_taxon_name_and_municipality.py) permet de mettre à jour toutes les observations avec l'API taxhub et l'API de municipalité que tu souhaites.
Je vais réfléchir à d'autres possibilités...

Je suis totalement ouvert pour discuter de cela de vive voix si tu le souhaites.

@camillemonchicourt
Copy link
Member

OK je comprends mieux.
C'est bien pour ça que l'on intègre le ref_geo et le référentiel taxonomique dans les BDD, pour bien garder des BDD puissantes et propres.
Je pense que les API ont leur intérêt mais aussi leurs limites.

Selon moi, c'est clairement pas une bonne idée de supprimer ces 2 schémas de la BDD de GeoNature-citizen et ça amène à faire des choses qui me paraissent un peu tordues comme de stocker cd_nom et nom_taxon en dur, ne bénéficiant plus de la puissance de Taxref et de ses évolutions.
Ou alors de ne pas bénéficier de la puissance, précision et référence du ref_geo.
Dans mon cas, je ne voudrais pas baser mes données sur Nominatim qui n'est pas un référentiel national reconnu.
Et pas non plus stocker et dupliquer le code_insee et le nom de la commune.
Si l'API est paramétrable, c'est une bonne chose, mais je préférerai clairement utiliser mon ref_geo.
Bon là c'est GeoNature-citizen, donc moins sensible à la précision que GeoNature, mais au final c'est le même type de données.

Pour moi, la vraie solution serait que TaxHub et le ref_geo puissent être installés comme des sous-modules, avec leurs BDD, modèles et routes, comme c'est le cas de UsersHub-authentification-module.

@mvergez
Copy link
Author

mvergez commented Dec 8, 2021

La problématique que je vois avec les schémas ref_geo et taxonomie c'est la copie de la donnée et donc la date de validité de la donnée. Par exemple si j'ai un citizen qui a sa propre base de donnée et un taxhub séparé, j'ai une duplication du schéma taxonomique alors que ce sont des données identiques. Et à chaque changement de version de taxref, je devrai procéder à la mise à jour 2 fois. Alors que je pourrai appeler la même instance unique.

Le ref_geo est très intéressant car c'est un standard de referentiel national. Mais il n'est valable qu'en France. Or Citizen a une vocation internationale. Je te rejoins sur le paramétrage de l'API, où chacun pourrait brancher son référentiel. Selon nous, l'idéal pour un prochain développement serait alors d'ensiler le ref_geo dans une API propre.

Et pas non plus stocker et dupliquer le code_insee et le nom de la commune.

Petite précision : nous stockons uniquement le nom de la commune dans Citizen ce qui nous paraît suffisant.

@camillemonchicourt
Copy link
Member

Ah non surtout pas.
Justement quand on a une BDD qui comprend un référentiel, il ne faut surtout pas la dupliquer en dur dans d'autres BDD et alors ne plus avoir de lien entre les 2.
Il faut absolument être dans une logique de BDD mère et BDD filles.

C'est le cas dans GeoNature-atlas, où on a bien les schémas taxonomie et ref_geo mais sans les dupliquer manuellement et devoir les mettre à jour à 2 endroits.
Dans le cas de GeoNature-atlas, on fait simplement des FDW, comme ça on a les données disponibles localement et à jour quand on modifie les données dans la BDD mère.

Le ref_geo est une structure de BDD avec des fonctions associées, ce n'est pas un référentiel de données.
On le fournit avec des données françaises de base à l'installation pour faciliter son utilisation, mais son contenu est clairement fait pour être adapté localement, voire à totalement remplacé son contenu avec un territoire particulier, un autre pays, etc...

@camillemonchicourt
Copy link
Member

Sujet évoqué ici il y a quelques temps : #100

@mvergez
Copy link
Author

mvergez commented Dec 8, 2021

OK pour le FDW, mais à mon avis cela alourdirait le code et l'installation même automatique.
Sur Citizen, un seul appel à l'API suffit pour obtenir le nom d'une ville. J'ai l'impression qu'on a supprimé pas mal de ligne de code en supprimant ces 2 schémas.
Avec un FDW ici il faudrait lancer une commande SQL qui fait une intersection postgis avec l_areas avec un join sur les municipalités.

Je partirais plus sur un service ref_geo qui possède une base de donnée et une API. Cela pourrait bénéficier à des applications autres que GeoNature.

Je pense qu'on est d'accord dans le fond, c'est juste une histoire de préférences entre SQL et API. A voir pour la performance par contre, à tester...

@camillemonchicourt
Copy link
Member

Non je ne suis pas d'accord, ce n'est pas qu'une question de préférences entre API et SQL.
Le résultat et les conséquences ne sont pas les mêmes pour la qualité et la cohérence des données dans le temps.

Par exemple stocker en dur le nom du taxon en plus du cd_nom, alors que le nom (et même le cd_nom) peuvent évoluer dans Taxref, sans en garantir l'intégrité et la cohérence n'est pas anodin pour la qualité des données dans le temps.

Idem pour le fait de se baser sur un appel à une API Nominatim au moment de la saisie pour stocker l'information en dur, sans en garantir l'intégrité et la cohérence dans le temps n'est pas anodin non plus au niveau qualité des données.

Ce qui est important et doit être pérenne dans le temps sont les données.
Les applications sont secondaires et non pérennes.

@lpofredc
Copy link
Collaborator

lpofredc commented Dec 8, 2021

Bonjour @camillemonchicourt, @mvergez

Je me permets d'intervenir sur ces échanges et ces choix qui sont les miens.

  • cd_nom et nom d'espèce. Selon moi, l'information importante est le cd_nom utilisé à un instant T (je ne comprends d'ailleurs pas pourquoi, quelque chose doit m'échapper, des cd_nom peuvent disparaitre de TaxRef, c'est un référentiel taxonomique mais aussi un référentiel synonymique). Selon moi, la donnée d'origine (avec son cd_nom original donc) doit primer. Concernant le nom de l'espèce, ce n'est selon moi qu'une information subsidiaire utilisée pour aider à la gestion des données en backoffice et ainsi éviter de générer des process complexe et lourds. N'est-ce d'ailleurs pas ce qui existe déjà dans la synthèse geonature avec le champ nom_cite?

  • commune. J'ai en effet demandé à privilégier nominatim (basé sur OpenStreetMap) car plus universel et sans frontieres (GeoNature-citizen est actuellement utilisé en Belgique par exemple). L'installation du ref_geo n'etait pas sans lourdes conséquences (36000 communes qui ne représentaient par ailleurs que la France Métropolitaine). Citizen est parfois utilisé sur de simple communes dans le cadre d'un ABC/ABT, et les personnes amenées à l'installer sont possiblement peu voire pas du tout a l'aise avec l'administration de bdd pour ajouter elle-même leurs communes... Concrètement, L'usage de la commune dans Citizen est uniquement applicatif pour filtrer les données par commune dans une enquête. L'information de localisation importante pour une donnée est sa localisation géographique (X/Y/Z), et non sa commune de rattachement. D'autant plus que ces référentiels géographiques évoluent eux aussi dans le temps (fusion notamment).

Actuellement, les dépendances à TaxHub et au RefGeo sont très lourdes tant du point de vue du stockage (plus de 2.8Go en bdd!!!) que de la maintenance (ajout de complexité à l'installation, nécessité de maintient d'une cohérence par rapport aux évolution des applis sources (TaxHub et GeoNature-refgeo). J'ai à ce propos souvenir d'avoir commencé les développements du backend sur une version ref_geo qui avait évolué par la suite et qui avait provoqué des erreurs (models différents).

 ref_geo | taxonomie |   sum   
---------+-----------+---------
 463 MB  | 2407 MB   | 2869 MB

@camillemonchicourt
Copy link
Member

Oui intéressant.
Avec ces éléments je comprends mieux l'approche et les choix.
Ce sont des infos très secondaires dans Citizen qui ne méritent pas d'embarquer toute la complexité de TaxHub et du ref_geo, qui apportent pas ou peu à Citizen, en effet.

OK je comprends mieux.

A noter que le "nom cité" est un champs pas ou peu utilisé en affichage, mais pour garder la trace du nom utilisé lors de l'observation. C'est un peu différent du cas présent.
Mais en effet dans le cas de Citizen c'est le cd_nom qui est important et sera utilisé si la donnée est transmise ailleurs, dans un GeoNature, atlas ou autre. 👍

Pour le ref_geo, il ne faut vraiment pas le voir comme un référentiel de données avec les zonages français.
C'est un outil pour gérer un référentiel géographique et on le fournit avec des données sur la France pour faciliter son utilisation de base, mais il n'a pas vocation à rester en l'état et doit être limité au territoire, remplacé par des données plus précises ou sur un autre pays, ...
Mais en effet ça nécessite de l'administration de BDD qui n'est pas forcément simple et si ici on a juste besoin de la commune pour un affichage ou des filtres simples, le ref_geo n'est pas utile.

@mvergez
Copy link
Author

mvergez commented Dec 10, 2021

Non je ne suis pas d'accord, ce n'est pas qu'une question de préférences entre API et SQL.
Le résultat et les conséquences ne sont pas les mêmes pour la qualité et la cohérence des données dans le temps.

Juste pour préciser : je parlais d'une comparaison entre un FDW et une API. Dans un contexte d'isolation du ref_geo

@mvergez
Copy link
Author

mvergez commented Dec 10, 2021

Pour en revenir à la PR :
@lpofredc j'avais ajouté la municipalité avant la city... Désolé... C'est corrigé, l'ordre est maintenant : village > town > city > municipality (4938067).

J'ai également retiré la création du schéma ref_geo dans init_data.py (a0de8a5)

Tout est prêt de mon côté

Maxime Vergez added 2 commits December 14, 2021 14:29
Removed models and routes that are no longer needed
If the geoservice does not manage to get the municipality, do not
send the municipality to the backend and let the backend call the
nominatim API. It enables to get the city even if the user
internet connection is not really good
@mvergez
Copy link
Author

mvergez commented Dec 15, 2021

Bonjour,

Résumé des 2 derniers commits :

  1. Il restait encore les modèles du ref_geo ainsi que les routes associées : suppression
  2. Suite à un retour de @samuelpriou sur une municipalité non trouvée sur une observation, j'ai rendu plus robuste la fonction de recherche de municipalité :
    Si le frontend ne parviens pas à obtenir la municipalité par l'API de Nominatim (dû notamment à une faible connexion internet), le backend réitérera cet appel. A voir si cela est assez robuste

@lpofredc
Copy link
Collaborator

Bonjour,

Résumé des 2 derniers commits :

1. Il restait encore les modèles du ref_geo ainsi que les routes associées : suppression

2. Suite à un retour de @samuelpriou sur une municipalité non trouvée sur une observation, j'ai rendu plus robuste la fonction de recherche de municipalité :
   Si le frontend ne parviens pas à obtenir la municipalité par l'API de Nominatim (dû notamment à une faible connexion internet), le backend réitérera cet appel. A voir si cela est assez robuste

Ne serait-il pas plus simple de déléguer entièrement cette tâche au backend? Cela éviterai justement ces écueil liés à une mauvaise connexion et il n'y a d'autre usage que le rattachement géographique de la donnée côté front.

@mvergez
Copy link
Author

mvergez commented Dec 15, 2021

Effectivement, je pensais faire cela pour décharger le backend (même si cet appel ne doit pas consommer beaucoup de ressources). Je suis plus dans la philosophie de laisser au maximum au front faire les appels aux APIs.
Mais je suis d'accord que ça dédouble le code.

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

Successfully merging this pull request may close these issues.

3 participants