Evolution du standard "table schéma"

Bonjour à tous et à toutes,

J’ai préparé une « issue » pour faire évoluer le standard Table schéma (cf relationship_property.pdf) et je souhaite avoir au préalable votre avis sur la pertinence de cette évolution :

Je travaille depuis pas mal de temps sur la notion de « liste indexée » (cf présentation Ilist_technical.pdf) et il se trouve que cette notion est adaptée aux fichiers tabulaires (CSV) que l’on retrouve majoritairement dans les données partagées.

Cette notion permet notamment de définir les liens entre champs d’un fichier tabulaire et de contrôler que ces liens sont bien respectés. Quatre types de liens sont définis :

  • « coupled » : équivalent à une relation 1-1 dans un MCD (ex.lien entre une personne et un n° de sécurité sociale)
  • « derived » : équivalent à une relation 1-n dans un MCD (ex. lien entre un trimestre et plusieurs mois)
  • « crossed » : relation n-n avec tous les liens (ex.lien entre élève et matière scolaire dans le bulletin de note d’une classe : chaque élève a une note dans toutes les matières, chaque matière est controlée pour tous les élèves)
  • « linked » : pour tous les autres cas.

Ce type de relation entre champs peut être facilement mesuré et contrôlé (également à la saisie), c’est pourquoi je propose de l’ajouter dans les propriétés du standard Table Schéma.

A titre d’exemple, j’ai fait un test sur un des jeux de données disponibles sur data-gouv (j’ai pris celui des bornes de recharge, cf détail du test ici : test_IRVE.html) ) et les résultats me
semblent tout à fait intéressants :

  • sur les 49 champs qui composent le fichier, seuls 6 champs sont de type « derived » et 1 de type « coupled » alors que la mesure du taux de couplage entre champs montrent que la grande majorité devrait être de type « derived » ou « coupled »,
  • Par exemple, les champs ‹ consolidated_longitude › et ‹ consolidated_latitude › sont bien dérivés du champ ‹ coordonneesXY › (ce qui est tout à fait cohérent)
  • Par contre, les champs ‹ coordonneesXY › et ‹ nom-station › devraient être liés et on observe que pour 1% des données, ce n’est pas le cas. Par exemple, pour la position [1.106329, 49.474202], on trouve 10 stations [‹ SCH01 ›, ‹ SCH10 ›, ‹ SCH09 ›, ‹ SCH07 ›, ‹ SCH06 ›, ‹ SCH05 ›, ‹ SCH04 ›, ‹ SCH03 ›, ‹ SCH02 ›, ‹ SCH08 ›] et pour la station ‹ Camping Arinella › on trouve 5 positions: [’[9.445075, 41.995246]’, ‹ [9.445074, 41.995246] ›, ‹ [9.445073, 41.995246] ›, ‹ [9.445072, 41.995246] ›, ‹ [9.445071, 41.995246] ›]. Ceci est peut être dû à une confusion entre stations de recharge et bornes de recharge.

Cet exemple montre que cette information de lien entre champs est importante pour l’exploitation ultérieure des données (sinon, comment positionne t’on les stations sur une carte si une station a plusieurs positions ?)

Afin de me conforter sur l’intérêt de l’ajout d’une propriété « relationship » dans Table Schéma, est-ce que vous pouvez me donner votre retour :

  • est-ce que ça vous semble une bonne idée et est-ce nécessaire ?
  • est-ce que vous avez été confronté à des difficultés d’exploitation de données parce que les relations entre champs n’étaient pas bien définies ou mal contrôlées ?
  • dans les cas où cela est spécifié et contrôlé, quels étaient les outils utilisés pour le spécifier et le contrôler ?

Merci par avance pour votre retour (je mets également les fichiers en lien dans le corps du texte en PJ)

Bonne vacances pour ceux qui partent et bon courage pour ceux qui reviennent !!

test_IRVE.html (323,0 Ko)
relationship_property.pdf (164,6 Ko)
Ilist_technical.pdf (845,2 Ko)

2 « J'aime »

Bonjour,

Personnellement, je trouve cette information très intéressante, pas seulement en interne pour un jeu de données composé de plusieurs fichiers, mais in extenso pour identifier les colonnes pivots, et ainsi les données pivots

Mais si référence il y a, reste à pouvoir préciser vers quel fichier et quel champ

Dans TableSchema, notamment le SCDL, des références sont spécifiées par exemple pour les SIRET via les custom checks : schema.json · master · SCDL / Schéma de la composition des plats de la restauration collective · GitLab

Pour ce qui est du multi fichiers, une issue a été soulevée sur le github de schema.data.gouv.fr par rapport au multi tables.

En aparté, je trouverais intéressant d’avoir un catalogue des référentiels qui liste les valeurs de références : NAF, SIREN, SIRET, INSEE, etc… et en rende accessible le contenu.

Pour suggérer des évolutions à TableSchema, on peut aller sur Issues · frictionlessdata/specs · GitHub

Bonjour,
Merci pour ce retour positif !

En fait, la proposition est complémentaire aux notions de pivots notamment entre fichiers. Elle se limite à donner les moyens d’exprimer des dépendances entre colonnes (ex. entre une colonne ‹ trimestre › et une colonne ‹ mois › - un mois ne peut être associé qu’à un seul trimestre ou ex. entre une colonne ‹ station de recharge électrique › et ‹ coordonnées › - une station (fixe) ne peut disposer que d’une seule coordonnées.

Ce qui est intéressant est que les outils sont disponibles pour le contrôler à la saisie ou a posteriori et aussi mesurer les écarts et identifier les données en erreur.

Pour les évolutions de TableSchema, effectivement j’avais bien en tête de créer une Issue sur frictionlessdata/specs.

Je vais également creuser ces notions de pivots via les liens indiqués dans le mail.

Bonne journée

J’ai pour ma part un peu de mal à ce stade à comprendre la proposition et les subtilités relativement complexes qu’elle contient. Sans faire un procès en « over engineering », je pense qu’une synthèse simple du besoin auquel répond cette proposition et, surtout, un cas d’usage seraient utiles. Ils seront de toute façon nécessaires pour la faire avancer.

Si je comprends bien, comme le dit Mathieu, il s’agirait en effet de consolider des fonctionnalités actuelles de « custom check » ou avec une finalité équivalente. Si tel est le cas, il me semble que c’est une bonne idée et je vous remercie de la proposer ! je la résumerais tout simplement de la sorte : « Integrate custom checks into Table Schemas ».

Pour rappel les « custom checks », qui ont été mis à contribution dans le cadre du projet Validata et ajoutés à différents schémas à cette occasion (voir documentation ici), ne font pas partie de la spec Table Schema mais sont une fonctionnalité de la librairie frictionless-py utilisée par le projet Validata. Je serais donc favorable à ce que cette pratique qui a été éprouvée soit reprise, et étendue avec vos propositions.

En effet, il est peu probable que les schémas actuels soient modifiés si votre proposition va à l’encontre de l’usage déjà en place et il est donc préférable de s’appuyer sur ces pratiques pour les formaliser (« standardiser ») et en étendre les possibilités.

Concernant la méthode pour faire avancer de telles propositions : la pratique (qui personnellement me semble saine) dans le projet Frictionless Data est de faire évoluer la spécification en fonction des usages. Il est donc préférable d’abord de démontrer un usage réel et de proposer son implémentation dans frictionless-py et ensuite de proposer d’aligner la spec avec cette implémentation. C’est ainsi que nous avons pu ces dernières années intégrer un certain nombre des fonctionnalités dont le projet Validata (et schema.data.gouv.fr) avait besoin.

A noter que les travaux sur la v5 de frictionless-py ont lieu en ce moment et que pas mal de fonctionnalités sont ajoutées à cette occasion, c’est donc un moment opportun. :slight_smile:

Exemple de feature qui vient d’être intégrée de cette manière et qui me semble d’ailleurs dans le même esprit :

Bonjour Johan,

Merci pour ce retour. J’ai regardé rapidement la documentation des « custom check » et ça me permet de comprendre les différences avec la notion de « relationship » que je propose. La principale différence est que les « custom checks » s’intéressent aux valeurs des champs qui doivent être valides alors que les « relationship » ne traitent pas des valeurs qui peuvent être quelconques mais s’intéresse au modèle de données qui relient les différentes entités présentes en validant les relations 1 - 1, 1 - n et certaines relations n - n.

Effectivement l’argumentation est un peu théorique mais j’ai suivi votre conseil de présenter un exemple simple et concret qui est en pièce jointe et qui présente ce que pourrait apporter cette propriété sur une partie des données (pour rester simple) de la liste des IRVE (lien ici) ou
test_IRVE-simple.html (293,8 Ko)

Concernant le positionnement par rapport aux usages en place, je ne vois pas de contradictions par rapport aux spécifications (standard ou custom), ça ne peut qu’être un outil supplémentaire mis à disposition.

Pour la méthode, effectivement, c’est plus efficace de proposer et démontrer une implémentation sur le framework frictionless. Par contre, ça va me demande un peu de temps pour maîtriser le framework.

Je vais donc plutôt créer rapidement une issue uniquement avec la spec en vue de la V5 en précisant que je complèterai la demande avec une implémentation sous frictionless d’ici fin Aout.

Est-ce que ça vous semble correct comme approche ?

Bonne journée

Bonjour,

Merci pour cette proposition que je trouve intéressante. Tout ce qui contribue à la formalisation puis au contrôle de l’intégrité va dans le bon sens.

Toutefois comme @mrajerison je pense qu’il faut traiter les dépendances dans leur ensemble et pas seulement entre champs du même schéma. Situations qui par ailleurs peuvent poser problème, voir ci-dessous avec les IRVE.
D’ailleurs, même si TableSchema ne le permet pas complètement, j’ai travaillé avec d’autres formalisations qui permettaient de composer ses schéma par référencement de sous-parties (c’est le cas d’Avro notamment).

Donc il faut directement trouver une solution inter-fichiers, inter-schémas pour décrire complètement les relations d’intégrité dans tout l’espace de nommage et pas que pour un fichier donné.

La situation des IRVE que vous avez choisi est intéressante :

Cela montre surtout qu’il y a un problème de normalisation / redondance.
Le fichier national traduit deux concepts : les stations et les points de charge (en oubliant les bornes entre les deux, voir les définitions).

Ça ne peut pas tenir sur un seul fichier sans redondance.
Il faudrait avoir au moins 2 schémas et 2 fichiers séparés, en s’inspirant de ce qui a été fait pour les mesures de mobilité en distinguant les sites de mesures des mesures elles-même.

Ainsi je ne suis pas certain qu’introduire des outils pour encourager ces redondances au sein d’un même fichier soit souhaitable au lieu d’inciter à séparer en plusieurs fichiers lorsque c’est nécessaire.
J’insiste vraiment sur ce dernier point.

Pour rappel pour les lecteurs peu familiers de TableSchema, la possibilité existe de lier plusieurs tables entre elles avec des clés primaires/clés étrangères : Table Schema | Frictionless Standards

1 « J'aime »

Bonjour,

Cette réponse soulève plusieurs questions :

  • si on a plusieurs entités (au sens UML) est-ce qu’il faut un seul fichier ou plusieurs ?

    • je pense qu’il y a des avantages et inconvénients dans chacun des cas et que les deux approches doivent coexister. Le cas multifichier permet d’éviter les incohérences de duplication. Par contre cela peut générer des incohérences entre les fichiers. Par exemple si on a un fichier borne et un fichier point de charge, on pourrait avoir dans le premier fichier une borne déclarée alors qu’aucun point de charge n’est déclaré dans le second, ceci est évité avec un seul fichier. Le cas monofichier est aussi plus simple à gérer notamment dans les mises à jour. toujours sur l’exemple IRVE, l’application stricte du multifichier conduirait à avoir un fichier pour les aménageurs, un pour les opérateurs, un pour les stations et un pour les pdc, ce qui à l’usage pourrait être compliqué. Autre exemple d’un relevé de notes d’une classe, si on a les champs suivants : « nom », « age », « matière », « note ». il faudrait en toute rigueur avoir un fichier élève avec les champs « nom » et « age » et un autre pour les notes avec « nom », « matière », « note », ce qui n’est pas nécessaire. Il y a aussi une question de processus, si les données sont produites de façon non synchrone, le multi-fichiers s’impose (cf exemple mobilité pour les mesures). En synthèse, mon avis est que les deux doivent cohabiter et que le cas monofichier n’est pas à exclure notamment pour les entités avec peu d’attributs.
  • Est-ce que la duplication est à éviter ?

    • la aussi, je pense que c’est un sujet à débat et qu’il n’y a pas de vérité. Dans les inconvénients de la duplication il y a la question de la taille des fichiers mais on constate que la compression (ex. zip) élimine cet inconvénient. Par exemple, sur le fichier IRVE, on passe de 7,2 Mo pour le csv à 560 ko pour le fichier zippé. Il y a également d’autres solutions de représentation textuelle qui évitent la duplication (cf exemple IRVE en utilisant des « listes indexées » où l’on obtient une taille de 2,4 Mo au lieu de 7,3 Mo). L’autre inconvénient est celui du risque d’incohérence des données dupliquées mais celui-ci est éliminé par la proposition d’une propriété « relationship » (tous les attributs (champs) d’une même entité doivent être de type « dérivé » par rapport à son attribut (champs) principal) qui fonctionne aussi bien sur des données dupliquées que non dupliquées (et qui est simple à mettre en oeuvre → cf copie d’écran ci-dessous).
  • comment gérer les relations entre champs de fichiers différents ?

    • si on a bien un fichier pour chaque entité du modèle de données, les relations principales sont gérées avec la notion de clés (comme le rappelle Joël). Pour les relations plus complexes, une solution pourrait tous les fichiers dans un seul package et d’avoir un espace de nommage au sein du package, ce qui permettrait d’appeler les champs par leur nom « simple » pour les champs du fichier et par leur nom « long » pour les champs du package (sur l’exemple de la mobilité, on pourrait alors appeler le champ « fr_insee_code » du fichier site dans le fichier channel par son nom « site.fr_insee_code ». Est-ce que cette solution poserait des difficultés ?

Pour ne pas rater la V5, je vais proposer une issue rapidement sur frictionless pour la propriété « relationship » et je suis prêt à consacrer un peu de temps pour travailler sur les questions des fichiers différents.

Bonne journée

image

Bonjour !

Débat intéressant s’il en est.

TL;DR : Oui aux listes indexées comme capacité à garantir la cohérence entre valeurs métiers d’un enregistrement, pas pour encourager à la dénormalisation ou créer un anti-pattern aux clés étrangères.

Ces observations concernent ensuite le cas plus spécifique de dénormalisation qui ne devrait pas servir de justification aux listes indexées :

Je n’interdit pas la dé-normalisation, elle doit se faire pour de bonnes raisons. Cela se fait habituellement par facilité d’une minorité en répondant aux autres « deal with it ». On installe ainsi toutes sortes d’anti-pattern qui créent une dette technique qu’il faudra résoudre un jour.
Les concepts de normalisation ont au moins l’objectivité pour eux, ce qui évite les déséquilibres du genre tout en renforçant l’interopérabilité a priori.

« Il n’y a pas de vérité » parce que beaucoup d’acteurs voient leur usage plus important que celui du voisin alors qu’il y a un équilibre à trouver entre chaque.

Cela dépend du format choisi, je ne sais pas répondre.
Un fichier xlsx avec plusieurs tables par exemple sera entre les deux.

Si on a plusieurs entités, on a plusieurs entités.
Le choix d’un format ou d’un autre peut éventuellement nous inciter à les déformer en introduisant de la redondance. Ce sont ces déformations qu’il faut questionner, pas les rendre obligatoire en prétendant qu’on ne peut pas faire autrement.

C’est pourquoi j’ai beaucoup de réserves sur les cas d’usage proposés et leur justification.

Ces incohérences sont indépendantes du format.
Il est tout aussi possible d’avoir ces incohérences soit sous la forme d’enregistrements absents d’un des fichiers ou bien des colonnes vides dans le cas d’un unique fichier.

Le cas IRVE est vraiment bien choisi en revanche, parce que de quel usage parle-t-on ?
Aujourd’hui on se focalise sur les points de charge, ce qui est trop restrictif. Il y a le même sujet de qualité sur les aménageurs, exploitants, stations, bornes et points de charge.
Oui il faudrait plusieurs fichiers csv pour gérer ces multiples référentiels et pas seulement les points de charge.
Les entités, elles, sont bien connues depuis longtemps.

Dans tous les cas que nous soulevons ici, les données sont produites de manière asychrone :

  • L’exploitant d’un IRVE se déclare avant l’IRVE lui-même
  • La liste des élèves est connue avant le début de l’année scolaire, avant les notes obtenues pendant l’année
  • Les stations de mesures de mobilités sont connues avant le début des mesures

On va se dire qu’on va déduire la liste des exploitants d’après la liste de ce qu’ils exploitent. Cela fait parti des anti-pattern que j’évoque au début de ce post.
J’attire notre attention sur le fait que c’est sûrement le format qui nous inciterait à ces mauvaises pratiques.

La compression n’est applicable qu’au transport, lors du traitement on est tenu de charger la totalité des enregistrements, ce qui peut poser des soucis en RAM notamment.

Cela me semble être une bonne solution, sans avoir besoin de matérialiser le package en tant que tel, les schémas suffisent.
L’espace de nom existe déjà au travers d’une racine commune des noms longs, c’est ce que fait Avro par exemple.

Bonjour,

Pour info, j’ai déposé la proposition d’ajout d’une propriété « relationship » dans TableSchema.

issue TableSchema 803

Bonne journée

1 « J'aime »