Migrons des données !
S’il y a bien une opération que j’ai été amenée à réaliser régulièrement au fil de ma carrière, c’est de migrer des données, et plus particulièrement migrer des données catalographiques. Que ce soit de passer de Winisis à Koha, d’Antigone à PMB, de Microsoft Access à PMB, etc.
Et avec le temps, ma méthode a évoluée : du script ad hoc à l’utilisation de Catmandu. Et si les scripts m’ont été fort utiles pour faire mes armes en tant que programmeur, je dois bien reconnaître que j’apprécie maintenant de pouvoir travailler avec Catmandu pour faire cela ! C’est bien plus puissant, simple et cela me fait gagner énormément de temps.
Dans le billet d’aujourd’hui, je vous propose donc de migrer un jeu de
données avec Catmandu. Et pour comme jeu de données, je vais
simplement prendre le fichier records.csv
d’un des jeux de données
de la British
Library :
https://www.bl.uk/bibliographic/downloads/HGWellsResearcherFormat_202010_csv.zip.
Prendre connaissance des données
La première étape est simplement de prendre connaissance des données à disposition. Avec Catmandu, je peux afficher les données de la manière suivante :
catmandu convert CSV --file records.csv to YAML
Évidemment, cette commande affiche toutes les données, ce qui n’est pas idéal pour un premier contact.
Mais la commande convert accepte un argument permettant de limiter le nombre de données à traiter :
catmandu convert --total 1 CSV --file records.csv to YAML
Le résultat est maintenant plus facile à lire :
---
All names: Archer, William, critic [person]
Archival Resource Key: ''
BL record ID: '000105518'
BL shelfmark: 03558.de.30
BNB number: ''
Content type: Language material ; Text
Country of publication: England
Date of creation/publication: '1917'
Dates associated with name: ''
Dewey classification: ''
Edition: ''
Genre: ''
ISBN: ''
Languages: English
Material type: Volume
Name: Archer, William
Notes: ''
Number within series: ''
Physical description: 126 pages (8°)
Place of publication: London
Provenance: ''
Publisher: Watts
Role: critic
Series title: ''
Title: 'God and Mr. Wells: a critical examination of ''God, the Invisible King.'''
Topics: Wells, H. G. (Herbert George), 1866-1946
Type of name: person
Type of resource: Monograph
Variant titles: ''
...
Sur base de cette notice, on peut voir qu’il y a des champs vides. Une analyse de ces champs peut amener une meilleure connaissance des données à migrer. Catmandu permet également d’offrir une analyse rapide via Catmandu-Breaker. Le traitement se fait en deux étapes :
- La transformation des données dans le format Breaker via la
commande suivante :
catmandu convert CSV --file records.csv to Breaker --file hg_wells.breaker
- L’analyse proprement dite :
catmandu breaker hg_wells.breaker
.
Sur base du fichier, voici les résultats :
| name | count | zeros | zeros% | min | max | mean | variance | stdev | uniq~ | uniq% | entropy |
|------------|-------|-------|--------|-----|-----|--------------------|----------|-------|--------|-----------|--------------|
| # | 1753 | | | | | | | | | | |
| All | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 570 | 32.6 | 4.8/10.6 |
| Archival | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 60 | 3.4 | 0.4/10.8 |
| BL | 3506 | 0 | 0.0 | 2 | 2 | 2 | 0.0 | 0.0 | 3242 | 92.5 | 11.3/11.8 |
| BNB | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 698 | 39.9 | 4.7/10.8 |
| Content | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 5 | 0.3 | 0.4/10.8 |
| Country | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 51 | 2.9 | 2.4/10.8 |
| Date | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 197 | 11.2 | 6.4/10.1 |
| Dates | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 93 | 5.3 | 1.7/10.8 |
| Dewey | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 92 | 5.3 | 2.4/10.8 |
| Edition | 208 | 1545 | 88.1 | 0 | 1 | 0.118653736451797 | 0.1 | 0.3 | 92 | 44.4 | 1.2/10.8 |
| Genre | 371 | 1382 | 78.8 | 0 | 1 | 0.211637193382772 | 0.2 | 0.4 | 64 | 17.3 | 1.6/10.8 |
| ISBN | 723 | 1030 | 58.8 | 0 | 1 | 0.412435824301198 | 0.2 | 0.5 | 698 | 96.6 | 4.8/10.7 |
| Languages | 1699 | 54 | 3.1 | 0 | 1 | 0.969195664575014 | 0.0 | 0.2 | 44 | 2.6 | 1.2/10.8 |
| Material | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 12 | 0.7 | 0.7/10.8 |
| Name | 1693 | 60 | 3.4 | 0 | 1 | 0.965772960638905 | 0.0 | 0.2 | 285 | 16.9 | 2.6/10.7 |
| Notes | 469 | 1284 | 73.2 | 0 | 1 | 0.267541357672561 | 0.2 | 0.4 | 419 | 89.4 | 3.0/10.8 |
| Number | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 253 | 14.5 | 1.8/10.8 |
| Physical | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 1178 | 67.2 | 9.1/10.6 |
| Place | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 238 | 13.6 | 3.7/10.7 |
| Provenance | 11 | 1742 | 99.4 | 0 | 1 | 0.0062749572162008 | 0.0 | 0.1 | 12 (!) | 109.1 (!) | 0.1/10.8 (!) |
| Publisher | 1517 | 236 | 13.5 | 0 | 1 | 0.865373645179692 | 0.1 | 0.3 | 512 | 33.8 | 7.0/10.4 |
| Role | 273 | 1480 | 84.4 | 0 | 1 | 0.155733029092983 | 0.1 | 0.4 | 10 | 3.7 | 0.7/10.8 |
| Series | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 330 | 18.8 | 3.5/10.7 |
| Title | 1712 | 41 | 2.3 | 0 | 1 | 0.976611523103252 | 0.0 | 0.2 | 965 | 56.4 | 9.1/10.3 |
| Topics | 673 | 1080 | 61.6 | 0 | 1 | 0.383913291500285 | 0.2 | 0.5 | 373 | 55.5 | 3.6/10.7 |
| Type | 3506 | 0 | 0.0 | 2 | 2 | 2 | 0.0 | 0.0 | 12 | 0.3 | 1.3/11.8 |
| Variant | 1753 | 0 | 0.0 | 1 | 1 | 1 | 0.0 | 0.0 | 246 | 14.1 | 2.4/10.7 |
Overflow warning - probably your dataset is too small for an accurate uniq~, uniq% and entropy count...
Cela nous permet de dégager quelques éléments :
- Nous avons 1753 notices ;
- Nous avons quelques champs qui sont régulièrement vides : Provenance, Edition, etc.
Il y a encore probablement pas mal d’actions que nous pourrions faire sur un jeu de données plus complexe, mais à ce stade, nous pouvons passer à l’étape suivante.
Établir une table de correspondance
Pour migrer les données, je vais devoir faire correspondre un champ du fichier d’entrée, à un champ dans le format de sortie. Dans mon cas, je vais produire un fichier UNIMARC, qui est souvent facilement importable dans les logiciels de gestion de bibliothèque.
Dans le fichier records.csv
la première ligne contient le nom des
colonnes. Je peux la récupérer de la manière suivante :
catmandu convert --total 1 CSV --header 0 --file records.csv to YAML
Ce qui nous donne le résultat suivant :
---
'0': BL record ID
'1': Type of resource
'10': Role
'11': All names
'12': Title
'13': Variant titles
'14': Series title
'15': Number within series
'16': Country of publication
'17': Place of publication
'18': Publisher
'19': Date of creation/publication
'2': Content type
'20': Edition
'21': Physical description
'22': Dewey classification
'23': BL shelfmark
'24': Topics
'25': Genre
'26': Languages
'27': Notes
'28': Provenance
'3': Material type
'4': BNB number
'5': Archival Resource Key
'6': ISBN
'7': Name
'8': Dates associated with name
'9': Type of name
...
Je peux maintenant compléter ce « tableau » :
---
'0': BL record ID → 001
'12': Title → 200$a
'17': Place of publication 210$a
'18': Publisher → 210$c
'19': Date of creation/publication → 210$d
'21': Physical description → 215$a
'27': Notes → 300$a
'6': ISBN → 010$a
'7': Name → 700$a, 700$b, 700$4 → 070
...
Bon, comme vous pouvez le voir, j’ai fait preuve de paresse^W pédagogie : les autres colonnes sont laissées comme exercice au lecteur !
La migration proprement dite
Catmandu fournit un langage, nommé Fix permettant de manipuler les données.
Voici ce que cela donne :
vacuum()
marc_add('001', ind1 => ' ', ind2 => ' ', _ => $.0)
marc_add('010', ind1 => ' ', ind2 => ' ', a => $.6)
marc_add('200', ind1 => '1', ind2 => ' ', a => $.12)
marc_add('210', ind1 => ' ', ind2 => ' ', a => $.17, c => $.18, d => $.19)
marc_add('215', ind1 => ' ', ind2 => ' ', a => $.21)
marc_add('300', ind1 => ' ', ind2 => ' ', a => $.27)
split_field($.7, ', ')
if exists($.7.0)
trim($.7.0)
trim($.7.1)
marc_add('700', ind1 => ' ', ind2 => '1', a => $.7.0, b => $.7.1, 4 => '070')
end
- La commande
vacuum()
permet de supprimer les champs vides ; marc_add
permet de créer un champ ISO2709 et ses sous-champs ;- L’expression
$.0
signifie de prendre la valeur de la colonne 0 (donc la première colonne) ; split_field
permet découper un champ sur base d’une séquence de caractère ;- Et enfin,
trim
permet de supprimer les éventuels espaces en début et en fin d’une chaîne de caractère.
Et voici la commande à utiliser pour produire un fichier UNIMARC au format ISO2709 :
catmandu convert --start 1 CSV --header 0 --file records.csv to MARC --fix bl_records.fix --type ISO --encoding utf-8 --file bl_records.mrc
Et nous pouvons vérifier le résultat avec yaz-marcdump
:
00241 2200085 4500
001 000105518
200 1 $a God and Mr. Wells: a critical examination of 'God, the Invisible King.'
210 $a London $c Watts $d 1917
215 $a 126 pages (8°)
700 1 $a Archer $b William $4 070
00322 2200097 4500
001 000128859
200 1 $a Commentary; or Reply to H. G. Wells: his views in the book The common sense of war and peace
210 $a Liverpool $d 1970
215 $a 2 parts, ff 17, 20, 33 cm
300 $a Reproduced from typewriting
700 1 $a Ashton $b Charles Frederick $4 070
00414 2200097 4500
001 000194501
200 1 $a The Journal of a Disappointed Man ... With an introduction by H. G. Wells
210 $a London $c Chatto & Windus $d 1919
215 $a x, 312 pages (8°)
300 $a Other edition: The Journal of a Disappointed Man ... With an introduction by H. G. Wells. pp. x. 346. Chatto & Windus: London, 1923. 8º
700 1 $a Barbellion $b W. N. P. $4 070
Et j’ai maintenant un fichier que je peux importer dans le SIGB de mon choix.
Évidemment, le fichier produit est loin d’être parfait (le complément du titre fait partie du titre, tous les champs ne sont pas traités, la description matérielle pourrait être améliorée aussi), mais en quelques lignes de Fix, nous avons déjà un résultat utile et importable. La tâche équivalente dans un langage de programmation, que cela Perl ou Python, prendra beaucoup plus de temps à écrire. Mais je garderai ces langages pour réaliser d’autres opérations, plus complexes, en lien avec la migration : dédoublonnage, nettoyage des données, etc.