Transfert de données Oracle via Azure Data Factory

Alexandre LANGEOIS
Publié par Alexandre LANGEOIS
Catégorie : Azure / Azure Data Factory / Azure Functions
18/02/2021

Azure Data Factory (ADF) est le composant ETL (Extract Transform Load) de l’environnement Microsoft Azure. Il permet de créer des pipelines pour ingérer, modifier ou déplacer des informations depuis de nombreux silos de données. En l’occurrence, il peut être utilisé pour transférer des données depuis ou vers une base Oracle on-premise.

Cependant, pour pouvoir utiliser une ressource hébergée dans un réseau privé, il est nécessaire d’installer auparavant un Self-Hosted Integration Runtime (SHIR). Il gère la connexion vers les systèmes on-premise, telle qu’une base de données Oracle. Pour installer et paramétrer un SHIR sur une machine qui a accès à votre réseau, je vous renvoie vers la documentation Microsoft : ici.

 

Activité de copie

 

Une fois le SHIR configuré, vous pouvez vous connecter à Oracle comme à n’importe quelle autre source de données sur ADF. Pour la plupart des flux, une simple activité de copie sera suffisante. Pour l’exemple nous allons créer un flux d’une base Oracle à une autre. Pour cela, après avoir ajouté un nouveau pipeline, sélectionnez l’activité « copy data ».

 

Copy Oracle Data

 

Il ne nous reste plus qu’à paramétrer les bases de données ‘source’ et sink’. Dans les deux cas, il faut créer un nouveau dataset dans l’onglet correspondant et choisir Oracle.

 

Dataset Oracle

 

Une fois le dataset initialisé, il nous reste à le paramétrer en utilisant un « Linked Service » qui nous permettra d’accéder aux données à travers le SHIR. Pour cela, ouvrez le nouveau dataset et sélectionnez « new Linked Service ». Une fenêtre s’ouvre. Il faut compléter les informations de connexion pour pouvoir requêter la base Oracle.

 

Informations de connexion

 

Pour aller un peu plus loin :

  • Dans le cas du source dataset, il est possible d’utiliser une partition pour accélérer le transfert de gros volumes de données. Celle-ci peut être physique (on utilise une partition déjà existante en base) ou dynamique. Dans le second cas, on peut utiliser n’importe quelle colonne d’entier (Int32) pour séparer l’extraction en plusieurs requêtes. Plus d’information ici.

 

Source Dataset

 

  • Si aucune partition n’existe et qu’il n’y a pas de colonne candidate pour créer une partition dynamique. Il existe une troisième solution : un pattern proposé directement par Azure qui permet de séparer le transfert en plusieurs requêtes SQL qui sont contenues dans une table tierce. Vous pouvez le retrouver directement dans les templates proposés sur ADF sous le nom « Bulk copy from Database », et l’adapter pour Oracle.
  • Dans le cas du sink dataset, on peut utiliser le champ pre-copy script pour préciser une commande SQL qui sera exécutée avant d’insérer les nouvelles données. Par exemple pour supprimer les lignes d’une table avant d’en rajouter. Attention, ce champ est quand même assez limité, on ne peut y exécuter qu’une commande. On va voir comment utiliser des requêtes plus complexes.

 

sink_dataset

 

Utiliser une procédure Oracle

 

Précédemment nous nous sommes placés dans le cas simple où seule une activité de copie était utilisée pour le transfert. Toutefois, pour des flux plus complexes, lorsque de simple requêtes SQL ne sont pas suffisantes, il peut être nécessaire de faire appel à une procédure pour gérer une partie du processus.

L’activité « Stored procedure » de ADF est limitée principalement au SQL et ne permet pas d’interagir directement avec une procédure Oracle. On va donc utiliser un service externe d’Azure pour le faire. Deux choix principaux s’offrent à nous : une Logic App ou une Azure Function. Les deux fonctionnent, toutefois on privilégiera la deuxième possibilité, car dans le premier cas, il nous faudrait installer des drivers Oracle.

A l’instar du SHIR, notre Azure fonction va avoir besoin d’un intermédiaire pour accéder aux ressources on-premise. Il s’agit d’un Hybrid Connection Manager. Si vous n’en avez pas encore un, je vous renvoie à la documentation Azure pour l’installer : ici.

Une fois tout cela configuré, il ne reste plus qu’à écrire cette Azure Function. Pour interagir avec Oracle, on va utiliser le package nuget « Oracle.ManagedDataAccess.Core ». Et pour pouvoir appeler notre Azure function depuis ADF, on utilisera un trigger HTTP. Voici le code : on se contente d’accéder à la base de données et à lancer une procédure déjà écrite.

 

using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Oracle.ManagedDataAccess.Client;

namespace fa_ScoreCards_CBR
{
    public static class Call_Proc_Oracle_ScoreCards
    {
        private static readonly string CONNECTION_STRING = "yourConnectionString";

        [FunctionName("Call_Proc_Oracle_ScoreCards")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
            ILogger log)
        {
            var orclCon = new OracleConnection(CONNECTION_STRING);
            try
            {
                orclCon.Open();

  // Creation of the Query
                OracleCommand orclCmd = orclCon.CreateCommand();
                orclCmd.CommandType = System.Data.CommandType.StoredProcedure;
                orclCmd.CommandText = "yourStoredProcedureName";
                orclCmd.ExecuteNonQuery();

                orclCmd.Dispose();
                orclCon.Close();

            } catch (System.Exception Ex)
            {
                log.LogError(Ex.Message);
                throw (new System.Exception(Ex.Message));
            } finally
            {
                orclCon.Close();
            }
            return new OkResult();
        }
    }
}

 

Une fois, ce code adapté et l’Azure function déployée, on récupère son URL. On peut ensuite l’appeler avec une activité « Web » en amont ou en aval de notre activité de copie.