Menu toggle
ARCHIVE
Ceci est une archive de mon ancien blog Defense de me faire travailler.

SchemaCrawler est un framework open-source de découverte de base de données sur jdbc. Il permet de récupérer facilement les métadonnées de la base étudiée. Le framework est aussi publié sous forme d'outil indépendant à utiliser en ligne de commande. Il permet par exemple d'extraire un fichier de description d'une base.

SchemaCrawler permet ainsi de récupérer les informations suivantes :

  • Liste des catalogs (rarement utilisés)
  • Liste des schémas
  • Liste des tables, vues, routines, triggers, contraintes...
  • Liste et détails des champs

Une recherche en deux étapes

La récupération des métadonnées se fait en deux étapes :

  • La définition des options de recherche
  • Le lancement de la recherche sur une connection jdbc

Les options de recherche

La définition des options de recherche est la phase la plus longue et complexe. Des options mal configurées engendrent des temps de réponse très long et une quantité d'informations inutiles et parasites importante. Il est nécessaire de filtrer tout ce que l'on ne souhaite pas récupérer.

Pour filtrer les éléments à conserver, SchemaCrawler met à disposition des objets InclusionRule qui prennent en paramètre une regExp à inclure et une regExp à exclure.

Dans l'exemple suivant, nous définissons un objet option de schemaCrawler permettant de ne récupérer aucune table, aucune vue, aucune procédure, aucun champ... Ainsi nous ne récupérons que la liste des schémas/catalogs de la base.

// Création d'un objet option de SchemaCrawler
SchemaCrawlerOptions options = new SchemaCrawlerOptions();

// On n'autorise aucun type de tables (tables, vues...)
TableType[] types = {};
options.setTableTypes(types);

// On exclue toutes les procédures (inclure rien, exclure tout)
InclusionRule procedureInclusionRule = new InclusionRule("", ".*");
options.setProcedureInclusionRule(procedureInclusionRule);

// On exclue toutes les colonnes des procédures (inclure rien, exclure tout)
InclusionRule procedureColumnInclusionRule = new InclusionRule("", ".*");
options.setProcedureColumnInclusionRule(procedureColumnInclusionRule);

// On exclue toutes les tables(inclure rien, exclure tout)
InclusionRule tableInclusionRule = new InclusionRule("", ".*");
options.setTableInclusionRule(tableInclusionRule);

// On fixe le niveau de détail des métadonnées au minimum
options.setSchemaInfoLevel(SchemaInfoLevel.minimum());

// On exclue les procédure stockées
options.setShowStoredProcedures(false);

Le lancement de la recherche

Le lancement de la recherche est la partie la plus simple. Il suffit de faire appel à la méthode SchemaCrawlerUtility.getDatabase et de passer en paramètre une connexion à la base de données valide (de type java.sql.Connection) et un objet option de schemaCrawler.

Database crawlingDatabase = SchemaCrawlerUtility.getDatabase(databaseConnection, options);

Une fois l'objet database de SchemaCrawler récupéré, il est très simple de parcourir les métadonnées. Par exemple pour tracer la liste des schémas de la base de données :

for (final Schema schema : crawlingDatabase.getSchemas()) {
    log.info("Found database schema " + schema.getSchemaName() + " in catalog " + schema.getCatalogName());
}

Différentes options intéressantes

Comme expliqué dans le chapitre précédent, la complexité d'utilisation de ce framework réside principalement dans la configuration de l'objet option permettant de spécifier correctement les informations à remonter pour réduire au maximum les temps de recherche en base (un scan complet de la base étant extrêmement long). Dans cette section, nous allons proposer deux exemples types de définition de l'objet option pour récupérer les schémas puis les tables et vues. Sur le même principe toutes les métadonnées de la base peuvent être récupérées.

Récupération de la liste des schémas

Idem chapitre précédant :

// Création d'un objet option de SchemaCrawler
SchemaCrawlerOptions options = new SchemaCrawlerOptions();

// On n'autorise aucun type de tables (tables, vues...)
TableType[] types = {};
options.setTableTypes(types);

// On exclue toutes les procédures (inclure rien, exclure tout)
InclusionRule procedureInclusionRule = new InclusionRule("", ".*");
options.setProcedureInclusionRule(procedureInclusionRule);

// On exclue toutes les colonnes des procédures (inclure rien, exclure tout)
InclusionRule procedureColumnInclusionRule = new InclusionRule("", ".*");
options.setProcedureColumnInclusionRule(procedureColumnInclusionRule);

// On exclue toutes les tables(inclure rien, exclure tout)
InclusionRule tableInclusionRule = new InclusionRule("", ".*");
options.setTableInclusionRule(tableInclusionRule);

// On fixe le niveau de détail des métadonnées au minimum
options.setSchemaInfoLevel(SchemaInfoLevel.minimum());

// On exclue les procédure stockées
options.setShowStoredProcedures(false);

Récupération de la liste des tables et vues

// Création d'un objet option de SchemaCrawler
SchemaCrawlerOptions options = new SchemaCrawlerOptions();

// On autorise les tables et les vues
TableType[] types = { TableType.table, TableType.view };
options.setTableTypes(types);

// On exclue toutes les procédures (inclure rien, exclure tout)
InclusionRule procedureInclusionRule = new InclusionRule("", ".*");
options.setProcedureInclusionRule(procedureInclusionRule);

// On exclue toutes les colonnes des procédures (inclure rien, exclure tout)
InclusionRule procedureColumnInclusionRule = new InclusionRule("", ".*");
options.setProcedureColumnInclusionRule(procedureColumnInclusionRule);

// On exclue les procédure stockées
options.setShowStoredProcedures(false);

// On inclue toutes les tables
//mais on exclue les tables commençant par $ (pour éviter les tables système d'Oracle)
InclusionRule tableInclusionRule = new InclusionRule(".*", ".*[\\x24]+.*");
options.setTableInclusionRule(tableInclusionRule);

// On fixe le niveau de détail des métadonnées au minimum
options.setSchemaInfoLevel(SchemaInfoLevel.minimum());

// On spécifie le schéma que l'on souhaite crawler
InclusionRule schemaInclusionRule = new InclusionRule("MySchema", "");
options.setSchemaInclusionRule(schemaInclusionRule);

Article rédigé pour la plateforme de capitalisation technique de Sword