Migration de bases de données Winisis - Première étape

| Aucun Commentaire | Aucun Trackback

Depuis quelques années maintenant, je suis régulièremnt contacté par mail pour communiquer les outils permettant de migrer des bases de données Winisis. Malheureusement, je n'ai jamais pris le temps de faire rédiger une documentation convenable, et c'est dommage. Je vais donc jeter les bases de cette documentation sur ce blog, et j'espère que je prendrai le temps dans le futur de mettre en place une documentation plus complète.

Avant de passer aux outils proprement dit, voici le cadre dans lequel ils ont été développés. Dans le cadre d'une formation organisée conjointement par l'Université Libre de Bruxelles (ULB) et par la Commission Universitaire pour le Développement (CUD). j'ai donné un cours nommé « Systèmes intégrés de gestion de bibliothèques ». Les stagiaires suivant cette formation devaient mener un projet, et un de ces stagiaires souhaitait migrer de Winisis vers Koha (c'était le logiciel servant d'illustration à mon cours). Je me suis donc penché sur la question. L'objectif était donc de migrer la base de données ISIS vers du MARC21.

Les bases de données s'appuyant sur un schéma spécifique à chaque utilisateur (Winisis n'est donc pas un SIGB, mais un SGBD, spécialisé dans les données bibliographiques, certes, mais un SGBD ; il ressemble donc plus à Microsoft Access qu'à Koha). la première étape consiste donc à déterminer la structure de la base de données de manière à établir une table de correspondance vers le format MARC souhaité (MARC21, Unimarc ou n'importe quelle autre variante). Aujourd'hui, je ne verrai que cette étape, et l'outil développé pour cela. Les autres étapes suivront dans les jours à venir.

La structure d'une base de données ISIS, nommé « Field Definition Table », donc « table de définition des champs », dans le jargon ISIS se trouve stocké dans un fichier texte dont l'extension est « .fdt ». En analysant ce fichier, on peut donc facilement déterminer la structure de la base de données. Biblio::Isis est le module de choix pour manipuler les bases de données ISIS, il offre une fonction permettant de lire cette table de définition des champs, et donc le code suivant est basé sur ce module :

#!/usr/bin/env perl

use strict;
use warnings;

use Getopt::Long;
use File::Find::Rule;
use Data::Dumper;
use Encode qw( from_to );
use Spreadsheet::WriteExcel;

my $config = {};

my %save_functions = (
    excel => \&_save_excel,
    dump  => \&_dump_struct,
);

my $fdt_struct = {};

GetOptions( $config, 'database=s', 'file=s', 'save=s' );

if ( not exists $config->{database} and not exists $config->{file} ) {
    die _usage();
}
else {
    my $fdt_file;
    if ( exists $config->{database} ) {
        $fdt_file = _get_fdt_file( $config->{database} );
    }
    else {
        $fdt_file = $config->{file};
    }
    $fdt_struct = _map_fdt_file($fdt_file);
    _print_fdt_struct($fdt_struct);
    _save_fdt_struct( $config->{save}, @ARGV ) if $config->{save};
}

sub _usage {
    return
"Usage: $0 [--database 'ISIS database' | --file 'ISIS.FDT' [--save excel|dump filename.xls]]\n";
}

sub _get_fdt_file {
    my $database = shift;

    if ( not -e $config->{database} ) {
        print "Unable to open the ISIS database: $database\n";
        return;
    }

    my @files =
      File::Find::Rule->file()->name( '*.fdt', '*.FDT' )
      ->in( $config->{database} );

    if ( scalar(@files) > 1 ) {
        print "Too many FDT files!\n";
        return shift(@files);
    }

    if ( scalar(@files) == 0 ) {
        print "No FDT files!!!\n";
        return;
    }

    return shift(@files);
}

sub _map_fdt_file {
    my $fdt_file = shift;

    my $fdt_struct = {};

    # Code heavily based on Biblio::Isis
    my $fieldzone = 0;

    open( my $fileFDT, $fdt_file ) or die "$fdt_file: $!\n";
    binmode($fileFDT);

    while (<$fileFDT>) {
        chomp;
        if ($fieldzone) {
            my $name       = substr( $_, 0,  30 );
            my $tag        = substr( $_, 50, 3 );
            my $repeatable = substr( $_, 61, 1 );

            $name =~ s/\s+$//;
            $tag  =~ s/\s+$//;

            $fdt_struct->{$tag} = {
                name       => from_to( $name, 'cp850', 'utf8' ),
                repeatable => $repeatable,
            };
        }

        if (/^\*\*\*/) {
            $fieldzone = 1;
        }
    }

    close($fileFDT);

    return $fdt_struct;
}

sub _print_fdt_struct {
    my $fdt_struct = shift;

    foreach my $tag ( keys %{$fdt_struct} ) {
        print "$tag\t=>\t" . $fdt_struct->{$tag}->{name} . "\n";
    }

    return;
}

sub _save_fdt_struct {
    my $save_function = shift;

    if ( exists $save_functions{$save_function} ) {
        if ( scalar(@_) > 0 ) {
            $save_functions{$save_function}->(@_);
        }
        else {
            die "No file where to put the schema\n";
        }
    }
    else {
        die "Save function <$save_function> doesn't exist\n";
    }
}

sub _save_excel {
    my $excel_filename = shift;

    my $excel = Spreadsheet::WriteExcel->new($excel_filename);
    my $ws    = $excel->add_worksheet();
    $ws->write( 0, 0, "Champ ISIS" );
    $ws->write( 0, 1, "Champ MARC21" );
    $ws->write( 0, 2, "Description" );

    my $row = 1;
    foreach my $tag ( sort keys %{$fdt_struct} ) {
        $ws->write( $row, 0, $tag );
        $ws->write( $row, 2,
            from_to( $fdt_struct->{$tag}->{name}, 'utf8', 'latin1' ) );

        $row++;
    }
}

sub _dump_struct {
    print Dumper $fdt_struct;
}

L'outil permet donc d'afficher la structure d'une base de données, mais aussi de créer un fichier Excel contenant cette structure. C'est ce fichier Excel qui servira de base de à la négociation pour mettre en place la table de correspondance nécessaire pour lancer la migration.

L'outil s'emploit de la manière suivante : ./fdt_reader.pl -f ISIS.FDT -s excel isis_db.xls. Le fichier isis_db.xls contient trois colonnes :

  1. la première est le champ ISIS ;
  2. la deuxième est le champ (et le sous-champs) MARC correspondant ;
  3. la troisième est la description associée au champs ISIS, et donc, sur base de cette description, on se fait une idée précise de la fonction de celui-ci.

Nous verrons la prochaine fois comment ce fichier Excel s'intègre dans le processus de migration.

Aucun Trackback

URL de Trackback : http://blog.bjornoya.be/mt-tb.cgi/29

Laisser un commentaire

À propos de cette note

Cette page contient une unique note de manu publiée le 27 avril 2010 13h38.

Dédoublonnage des données lors d'une migration est la note précédente de ce blog.

Découverte automatique des fils RSS est la note suivante de ce blog.

Retrouvez le contenu récent sur l'index principal ou allez dans les archives pour retrouver tout le contenu.

Pages

Powered by Movable Type 4.261