0 Abonnés · 12 Publications

Un fichier de valeurs séparées par des virgules (CSV) est un fichier texte délimité qui utilise une virgule pour séparer les valeurs. Chaque ligne du fichier est un enregistrement de données. Chaque enregistrement est constitué d'un ou plusieurs champs, séparés par des virgules. L'utilisation de la virgule comme séparateur de champs est à l'origine du nom de ce format de fichier. Un fichier CSV stocke généralement des données tabulaires (chiffres et texte) en texte brut, auquel cas chaque ligne comporte le même nombre de champs.

Article Iryna Mykhailova · Oct 23, 2025 6m read

Salut,

C'est moi encore 😁. Je travaille actuellement à la génération de fausses données patients à des fins de test avec Chat-GPT et Python. J'aimerais également partager mon apprentissage. 😑

Tout d'abord, créer un service d'API REST personnalisé est facile en utilisant %CSP.REST.

Commençons ! 😂

1. Créez une classe datagen.restservice qui étend %CSP.REST.

Class datagen.restservice Extends%CSP.REST
{
Parameter CONTENTTYPE = "application/json";
}

2. Ajoutez une fonction genpatientcsv() pour générer les données du patient et les regrouper dans une chaîne csv

0
0 18
Article Corentin Blondeau · Oct 13, 2025 4m read

Bonjour

Je vous soumets cet article en tant qu’état de l’art enrichi.
L’objectif est de réunir les différentes façons d’importer et d’exporter des CSV en un seul endroit.
Cet article est basé sur InterSystems 2024.1 .
N'hésitez pas à commenter pour rajouter des précisions.
Si vous voulez une deuxième partie sur l'export de CSV, faites le moi savoir.

Contexte

3
2 63
Article Iryna Mykhailova · Avr 22, 2024 3m read

Dans les versions récentes d'IRIS, une nouvelle commande puissante de chargement de données a été introduite dans SQL : LOAD DATA. Cette fonctionnalité a été hautement optimisée pour importer des données dans IRIS de manière extrêmement rapide, permettant d'insérer des centaines de gigaoctets de données en quelques secondes au lieu d'heures ou de jours.

Il s’agit d’une amélioration très intéressante. Cependant, un gros problème persiste lors du chargement des données. À savoir le temps et les tracas nécessaires pour :

0
0 59
Question Cécile Heuillet · Déc 21, 2023

Bonjour,

j'utilise une méthode en python sur une opération pour pouvoir générer un fichier csv à partir d'une table de lien. Cette méthode me génère l'erreur : ERREUR <Ens>ErrCanNotAcquireJobRootLock et cela me bloque complètement pour l'arrête de la production. Mon opération passe en statut "Queued" alors que le fichier est généré et mon message de retour est complet.

La méthode principale de l'opération est :

2
0 80
Article Sylvain Guilbaud · Jan 29, 2024 13m read

Nous avons un délicieux dataset avec des recettes écrites par plusieurs utilisateurs de Reddit, mais la plupart des informations sont du texte libre comme le titre ou la description d'un article. Voyons comment nous pouvons très facilement charger l'ensemble de données, extraire certaines fonctionnalités et l'analyser à l'aide des fonctionnalités du grand modèle de langage OpenAI contenu dans Embedded Python et le framework Langchain.

Chargement de l'ensemble de données

Tout d’abord, nous devons charger l’ensemble de données ou pouvons-nous simplement nous y connecter ?

Il existe différentes manières d'y parvenir : par exemple CSV Record Mapper vous pouvez utiliser dans une production d'interopérabilité ou même de belles applications OpenExchange comme csvgen.

Nous utiliserons Foreign Tables. Une fonctionnalité très utile pour projeter des données physiquement stockées ailleurs vers IRIS SQL. Nous pouvons l'utiliser pour avoir une toute première vue des fichiers de l'ensemble de données.

Nous créons un Foreign Server:

CREATE FOREIGN SERVER dataset FOREIGN DATA WRAPPER CSV HOST '/app/data/'

Et puis une table étrangère qui se connecte au fichier CSV:

CREATE FOREIGN TABLE dataset.Recipes (
  CREATEDDATE DATE,
  NUMCOMMENTS INTEGER,
  TITLE VARCHAR,
  USERNAME VARCHAR,
  COMMENT VARCHAR,
  NUMCHAR INTEGER
) SERVER dataset FILE 'Recipes.csv' USING
{
  "from": {
    "file": {
       "skip": 1
    }
  }
}

Et voilà, nous pouvons immédiatement exécuter des requêtes SQL sur dataset.Recipes: image

## De quelles données avons-nous besoin ? L’ensemble de données est intéressant et nous avons faim. Cependant, si nous voulons décider d'une recette à cuisiner, nous aurons besoin de plus d'informations que nous pourrons utiliser pour analyser.

Nous allons travailler avec deux classes persistantes (tables):

  • yummy.data.Recipe: une classe contenant le titre et la description de la recette et quelques autres propriétés que nous souhaitons extraire et analyser (par exemple Score, Difficulty, Ingredients, CuisineType, PreparationTime)
  • yummy.data.RecipeHistory: une classe simple pour enregistrer que faisons-nous avec la recette

Nous pouvons maintenant charger nos tables yummy.data* avec le contenu de l'ensemble de données:

do ##class(yummy.Utils).LoadDataset()

Cela a l'air bien, mais nous devons encore découvrir comment générer des données pour les champs Score, Difficulty, Ingredients, PreparationTime et CuisineType. ## Analyser les recettes Nous souhaitons traiter le titre et la description de chaque recette et :

  • Extraire des informations telles que Difficulté, Ingrédients, Type de Cuisine, etc.
  • Construire notre propre score en fonction de nos critères afin que nous puissions décider de ce que nous voulons cuisiner.

Nous allons utiliser ce qui suit :

  • yummy.analysis.Analysis - une structure d'analyse générique que nous pouvons réutiliser au cas où nous souhaiterions construire plus d'analyse.
  • yummy.analysis.SimpleOpenAI - une analyse qui utilise le modèle Embedded Python + Langchain Framework + OpenAI LLM.

LLM (large language models) sont vraiment un excellent outil pour traiter le langage naturel.

LangChainest prêt à fonctionner en Python, nous pouvons donc l'utiliser directement dans InterSystems IRIS en utilisant Embedded Python.

La classe complète SimpleOpenAI ressemble à ceci:

/// Analyse OpenAI simple pour les recettes
Class yummy.analysis.SimpleOpenAI Extends Analysis
{

Property CuisineType As %String;

Property PreparationTime As %Integer;

Property Difficulty As %String;

Property Ingredients As %String;

/// Run
/// Vous pouvez essayer ceci depuis un terminal :
/// set a = ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(8))
/// do a.Run()
/// zwrite a
Method Run()
{
    try {
        do ..RunPythonAnalysis()

        set reasons = ""

        // mes types de cuisine préférés
        if "spanish,french,portuguese,italian,korean,japanese"[..CuisineType {
            set ..Score = ..Score + 2
            set reasons = reasons_$lb("It seems to be a "_..CuisineType_" recipe!")
        }

        // je ne veux pas passer toute la journée à cuisiner :)
        if (+..PreparationTime < 120) {
            set ..Score = ..Score + 1
            set reasons = reasons_$lb("You don't need too much time to prepare it") 
        }
        
        // bonus pour les ingrédients préférés !
        set favIngredients = $listbuild("kimchi", "truffle", "squid")
        for i=1:1:$listlength(favIngredients) {
            set favIngred = $listget(favIngredients, i)
            if ..Ingredients[favIngred {
                set ..Score = ..Score + 1
                set reasons = reasons_$lb("Favourite ingredient found: "_favIngred)
            }
        }

        set ..Reason = $listtostring(reasons, ". ")

    } catch ex {
        throw ex
    }
}

/// Mettre à jour la recette avec les résultats de l'analyse
Method UpdateRecipe()
{
    try {
        // appeler d'abord l'implémentation de la classe parent
        do ##super()

        // ajouter des résultats d'analyse spécifiques à OpenAI
        set ..Recipe.Ingredients = ..Ingredients
        set ..Recipe.PreparationTime = ..PreparationTime
        set ..Recipe.Difficulty = ..Difficulty
        set ..Recipe.CuisineType = ..CuisineType

    } catch ex {
        throw ex
    }
}

/// Exécuter une analyse à l'aide de Embedded Python + Langchain
/// do ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(8)).RunPythonAnalysis(1)
Method RunPythonAnalysis(debug As %Boolean = 0) [ Language = python ]
{
    # load OpenAI APIKEY from env
    import os
    from dotenv import load_dotenv, find_dotenv
    _ = load_dotenv('/app/.env')

    # account for deprecation of LLM model
    import datetime
    current_date = datetime.datetime.now().date()
    # date after which the model should be set to "gpt-3.5-turbo"
    target_date = datetime.date(2024, 6, 12)
    # set the model depending on the current date
    if current_date > target_date:
        llm_model = "gpt-3.5-turbo"
    else:
        llm_model = "gpt-3.5-turbo-0301"

    from langchain.chat_models import ChatOpenAI
    from langchain.prompts import ChatPromptTemplate
    from langchain.chains import LLMChain

    from langchain.output_parsers import ResponseSchema
    from langchain.output_parsers import StructuredOutputParser

    # init llm model
    llm = ChatOpenAI(temperature=0.0, model=llm_model)

    # prepare the responses we need
    cuisine_type_schema = ResponseSchema(
        name="cuisine_type",
        description="What is the cuisine type for the recipe? \
                     Answer in 1 word max in lowercase"
    )
    preparation_time_schema = ResponseSchema(
        name="preparation_time",
        description="How much time in minutes do I need to prepare the recipe?\
                     Anwer with an integer number, or null if unknown",
        type="integer",
    )
    difficulty_schema = ResponseSchema(
        name="difficulty",
        description="How difficult is this recipe?\
                     Answer with one of these values: easy, normal, hard, very-hard"
    )
    ingredients_schema = ResponseSchema(
        name="ingredients",
        description="Give me a comma separated list of ingredients in lowercase or empty if unknown"
    )
    response_schemas = [cuisine_type_schema, preparation_time_schema, difficulty_schema, ingredients_schema]

    # get format instructions from responses
    output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
    format_instructions = output_parser.get_format_instructions()
    
    analysis_template = """\
    Interprete and evaluate a recipe which title is: {title}
    and the description is: {description}
    
    {format_instructions}
    """
    prompt = ChatPromptTemplate.from_template(template=analysis_template)

    messages = prompt.format_messages(title=self.Recipe.Title, description=self.Recipe.Description, format_instructions=format_instructions)
    response = llm(messages)

    if debug:
        print("======ACTUAL PROMPT")
        print(messages[0].content)
        print("======RESPONSE")
        print(response.content)

    # populate analysis with results
    output_dict = output_parser.parse(response.content)
    self.CuisineType = output_dict['cuisine_type']
    self.Difficulty = output_dict['difficulty']
    self.Ingredients = output_dict['ingredients']
    if type(output_dict['preparation_time']) == int:
        self.PreparationTime = output_dict['preparation_time']

    return 1
}

}

La méthode RunPythonAnalysis c'est ici qu'entre en jeu OpenAI :). Vous pouvez le lancer directement depuis votre terminal pour une recette donnée :

do ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(12)).RunPythonAnalysis(1)

Nous obtiendrons un résultat comme celui-ci :

USER>do ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(12)).RunPythonAnalysis(1)
======ACTUAL PROMPT
                    Interprete and evaluate a recipe which title is: Folded Sushi - Alaska Roll
                    and the description is: Craving for some sushi but don't have a sushi roller? Try this easy version instead. It's super easy yet equally delicious!
[Video Recipe](https://www.youtube.com/watch?v=1LJPS1lOHSM)
# Ingredients
Serving Size:  \~5 sandwiches      
* 1 cup of sushi rice
* 3/4 cups + 2 1/2 tbsp of water
* A small piece of konbu (kelp)
* 2 tbsp of rice vinegar
* 1 tbsp of sugar
* 1 tsp of salt
* 2 avocado
* 6 imitation crab sticks
* 2 tbsp of Japanese mayo
* 1/2 lb of salmon  
# Recette     
* Place 1 cup of sushi rice into a mixing bowl and wash the rice at least 2 times or until the water becomes clear. Then transfer the rice into the rice cooker and add a small piece of kelp along with 3/4 cups plus 2 1/2 tbsp of water. Cook according to your rice cookers instruction.
* Combine 2 tbsp rice vinegar, 1 tbsp sugar, and 1 tsp salt in a medium bowl. Mix until everything is well combined.
* After the rice is cooked, remove the kelp and immediately scoop all the rice into the medium bowl with the vinegar and mix it well using the rice spatula. Make sure to use the cut motion to mix the rice to avoid mashing them. After thats done, cover it with a kitchen towel and let it cool down to room temperature.
* Cut the top of 1 avocado, then slice into the center of the avocado and rotate it along your knife. Then take each half of the avocado and twist. Afterward, take the side with the pit and carefully chop into the pit and twist to remove it. Then, using your hand, remove the peel. Repeat these steps with the other avocado. Dont forget to clean up your work station to give yourself more space. Then, place each half of the avocado facing down and thinly slice them. Once theyre sliced, slowly spread them out. Once thats done, set it aside.
* Remove the wrapper from each crab stick. Then, using your hand, peel the crab sticks vertically to get strings of crab sticks. Once all the crab sticks are peeled, rotate them sideways and chop them into small pieces, then place them in a bowl along with 2 tbsp of Japanese mayo and mix until everything is well mixed.
* Place a sharp knife at an angle and thinly slice against the grain. The thickness of the cut depends on your preference. Just make sure that all the pieces are similar in thickness.
* Grab a piece of seaweed wrap. Using a kitchen scissor, start cutting at the halfway point of seaweed wrap and cut until youre a little bit past the center of the piece. Rotate the piece vertically and start building. Dip your hand in some water to help with the sushi rice. Take a handful of sushi rice and spread it around the upper left hand quadrant of the seaweed wrap. Then carefully place a couple slices of salmon on the top right quadrant. Then place a couple slices of avocado on the bottom right quadrant. And finish it off with a couple of tsp of crab salad on the bottom left quadrant. Then, fold the top right quadrant into the bottom right quadrant, then continue by folding it into the bottom left quadrant. Well finish off the folding by folding the top left quadrant onto the rest of the sandwich. Afterward, place a piece of plastic wrap on top, cut it half, add a couple pieces of ginger and wasabi, and there you have it.

                    
Le résultat doit être un extrait de code de démarque formaté selon le schéma suivant, incluant les caractères "```json" and "```" :
json
{
        "cuisine_type": string  // Quel est le type de cuisine de la recette ? Réponse en 1 mot maximum en minuscule
        "preparation_time": integer  // De combien de temps en minutes ai-je besoin pour préparer la recette ? Répondez avec un nombre entier, ou nul si inconnu
        "difficulty": string  // À quel point cette recette est-elle difficile ? Répondez avec l'une de ces valeurs : facile, normal, difficile, très difficile
        "ingredients": string  // Donnez-moi une liste d'ingrédients séparés par des virgules en minuscules ou vide si inconnu
}

                    
======RESPONSE
json
{
        "cuisine_type": "japanese",
        "preparation_time": 30,
        "difficulty": "easy",
        "ingredients": "sushi rice, water, konbu, rice vinegar, sugar, salt, avocado, imitation crab sticks, japanese mayo, salmon"
}

Ça à l'air bon. Il semble que notre invite OpenAI soit capable de renvoyer des informations utiles. Exécutons toute la classe d'analyse depuis le terminal :

set a = ##class(yummy.analysis.SimpleOpenAI).%New(##class(yummy.data.Recipe).%OpenId(12))
do a.Run()
zwrite a
USER>zwrite a
a=37@yummy.analysis.SimpleOpenAI  ; <OREF>
+----------------- general information ---------------
|      oref value: 37
|      class name: yummy.analysis.SimpleOpenAI
| reference count: 2
+----------------- attribute values ------------------
|        CuisineType = "japanese"
|         Difficulty = "easy"
|        Ingredients = "sushi rice, water, konbu, rice vinegar, sugar, salt, avocado, imitation crab sticks, japanese mayo, salmon"
|    PreparationTime = 30
|             Reason = "It seems to be a japanese recipe!. You don't need too much time to prepare it"
|              Score = 3
+----------------- swizzled references ---------------
|           i%Recipe = ""
|           r%Recipe = "30@yummy.data.Recipe"
+-----------------------------------------------------

## Analyser toutes les recettes ! Naturellement, vous souhaitez exécuter l’analyse sur toutes les recettes que nous avons chargées.

Vous pouvez analyser une gamme d’identifiants de recettes de cette façon :

USER>do ##class(yummy.Utils).AnalyzeRange(1,10)
> Recipe 1 (1.755185s)
> Recipe 2 (2.559526s)
> Recipe 3 (1.556895s)
> Recipe 4 (1.720246s)
> Recipe 5 (1.689123s)
> Recipe 6 (2.404745s)
> Recipe 7 (1.538208s)
> Recipe 8 (1.33001s)
> Recipe 9 (1.49972s)
> Recipe 10 (1.425612s)

Après cela, regardez à nouveau votre tableau de recettes et vérifiez les résultats.

select * from yummy_data.Recipe

image

Je pense que je pourrais essayer la pizza à la courge poivrée ou le kimchi coréen au tofu et au porc :). De toute façon, je devrai vérifier à la maison :)

Notes finales

Vous pouvez trouver l'exemple complet sur https://github.com/isc-afuentes/recipe-inspector

Avec cet exemple simple, nous avons appris à utiliser les techniques LLM pour ajouter des fonctionnalités ou analyser certaines parties de vos données dans InterSystems IRIS.

Avec ce point de départ, vous pourriez penser à :

  • Utiliser InterSystems BI pour explorer et parcourir vos données à l'aide de cubes et de tableaux de bord.
  • Créer une application Web et fournir une interface utilisateur (par exemple Angular) pour cela, vous pouvez exploiter des packages tels que RESTForms2 pour générer automatiquement des API REST pour vos classes persistantes.
  • Et pourquoi garder en base l'information indiquant les recettes que vous aimez et celles que vous n'aimez pas, puis d'essayer de déterminer si une nouvelle recette vous plaira ? Vous pourriez essayer une approche IntegratedML, ou même une approche LLM fournissant des exemples de données et construisant un cas d'utilisation RAG (Retrieval Augmented Generation).

Quelles autres choses pourriez-vous essayer ? Laissez-moi savoir ce que vous pensez!

0
0 208
Question Laurent Vilcoq · Nov 16, 2023

Bonjour,

Je dois récupérer quotidiennement la totalité des données d'une vue SQL externe pour générer un fichier csv unique. J'étais partie sur l'utilisation d'un service de type EnsLib.SQL.Service.GenericService mais cela ne me convient pas puisque chaque ligne de résultat de la requête SQL génère un message et une trace différents. Dois-je passer par une table de lien ? Créer un service de toute pièce en implémentant le OnProcessInput() ? Autre ?

Merci par avance pour votre aide.

Bien cordialement,

2
1 159
Article Guillaume Rongier · Oct 27, 2023 7m read

Récemment, @Anastasia Dyubaylo a publié un article (celui-ci) sur une nouvelle fonctionnalité d'IntegratedML pour les prédictions de séries chronologiques présentée par @tomdlors du Global Summit 2023, organisons donc un petit atelier pour la tester !

Introduction

Nous avons choisi comme sujet de cet atelier la prédiction des utilisateurs du métro de Valence, mois par mois, ligne par ligne. Pour ce faire, nous disposons de données mensuelles ventilées par ligne depuis 2022 ainsi que de données annuelles ventilées par ligne depuis 2017 que nous extrapolerons mensuellement.

Une fois compilé le nombre mensuel de passagers, nous pourrons créer un fichier CSV qui ressemblera à celui-ci :

Year,Month,Passengers,Line
2017,1,549007,1
2017,1,515947,2
2017,1,770564,3
2017,1,621256,5
2017,1,429640,7
2017,1,520692,9
2017,1,322392,4
2017,1,95473,6
2017,1,18188,8
2017,1,0,10

Nous avons inclus dans notre fichier csv une ligne finale ",,,," qui nous permettra de savoir quand le fichier est terminé.

Mappage des fichiers CSV

Bien que le mappage soit déjà effectué dans le projet inclus dans cet article, nous allons le détailler pour les utilisateurs qui ne sont pas familiers avec Record Mapper.

Comme vous pouvez le voir dans l'image précédente, la première ligne sera l'en-tête du fichier et nous avons les données pour l'année, le mois, le flux de passagers et la ligne. Pour enregistrer le CSV dans notre base de données IRIS, nous utiliserons la fonctionnalité Record Mapper, à laquelle nous accéderons via le portail de gestion à partir des options de menu Interopérabilité -> Construire -> Assistant d'enregistrement CSV Record Wizard. Une fois l'accès obtenu, nous remplirons les champs de la manière indiquée :

N'oubliez pas que notre fichier CSV comporte des en-têtes, c'est pourquoi nous avons coché l'option L'échantillon comporte une ligne d'en-tête. À partir de ces informations, IRIS génère automatiquement le mappage CSV, en affichant l'écran suivant :

Nous n'aurons pas besoin de changer quoi que ce soit et en cliquant sur Générer (Generate), le système créera automatiquement toutes les classes nécessaires pour le mappage CSV à partir de nos productions.

Configuration de la production

Jetons un coup d'œil à la production configurée qui fonctionne dans notre projet :

Comme nous le voyons, notre production est composée de 3 Composants Métier. Voyons un peu plus en détail le rôle de chacun d'entre eux :

CSVIn

Ce service d'affaires est de la classe EnsLib.RecordMap.Service.FileService, il nous permettra de capturer les fichiers CSV qui se trouvent dans un chemin indiqué dans sa configuration. Pour chaque ligne du fichier CSV capturée, il créera un objet du type MLTEST.PassengersMap.Record défini par le RecordMap configuré, dans notre cas PassengersMap, et l'enverra au composant métier indiqué dans TargetConfigNames.

PredictionModelGeneration

Ce Processus Métier est défini par la BPL MLTEST.BP.PopulateTable à partir de laquelle nous allons transformer les données brutes reçues dans le format le plus intéressant pour l'entraînement de notre modèle. Jetons un coup d'œil à la BPL :

Voyons cela en détail dans le diagramme :

Tout d'abord, nous vérifierons si l'objet reçu correspond à une donnée réelle ou s'il s'agit de l'indicateur de fin de fichier défini précédemment par nous.

L'objet N'EST PAS la fin du fichier :

Si ce n'est pas la fin du fichier, nous allons transformer les données brutes reçues en un élément plus utilisable par notre modèle et pour cela nous avons défini une petite DTL : MLTEST.DT.ParseDate.

Cette DTL va seulement générer un objet de type MLTEST.Data.PassengersInfo avec une date de type DateTime formée avec les données du CSV. Lorsque la transformation sera terminée, la BPL aura juste à sauvegarder l'objet (dans la variable contextuelle PassengersInfo) dans notre base de données.

set sc = context.PassengersInfo.%Save()
 if ($$$ISERR(sc))
 {
   set context.Result = "Error"set context.ErrorMessage = sc
 }
 else
 {
   set context.Result = "Success"
 }

L'objet se trouve à la fin du fichier :

Lorsque nous avons fini de lire le fichier, nous devons procéder au formatage des données pour que le modèle de Time Series (séries chronologiques) les comprenne. ATTENTION! Il faut prendre en considération les deux points suivants (et que je n'ai pas pris en compte 🙄) :

  1. Il est nécessaire d'avoir un champ de type DateTime qui sera utilisé pour continuer la série chronologique, un type Date ne sera pas suffisant..
  2. Les enregistrements doivent être ordonnés de l'enregistrement le plus ancien au plus récent pour que l'entraînement fonctionne correctement.

Si le modèle a déjà été généré, nous le supprimerons, ainsi que les données du tableau d'apprentissage. Le processus se poursuit comme suit :

 

Voyons chaque étape en détail :

  1. Nous effectuons une insertion massive avec les données transformées.
INSERTINTO MLTEST_Data.PassengersLine (DateOfData, Line1, Line2, Line3, Line4, Line5, Line6, Line7, Line8, Line9, Line10) 
SELECT DateOfData, 
(SELECTMAX(s1.Passengers) FROM MLTEST_Data.PassengersInfo s1 WHERE s1.Line = 1AND s1.DateOfData = s.DateOfData) as Line1, 
(SELECTMAX(s2.Passengers) FROM MLTEST_Data.PassengersInfo s2 WHERE s2.Line = 2AND s2.DateOfData = s.DateOfData) as Line2, 
(SELECTMAX(s3.Passengers) FROM MLTEST_Data.PassengersInfo s3 WHERE s3.Line = 3AND s3.DateOfData = s.DateOfData) as Line3, 
(SELECTMAX(s4.Passengers) FROM MLTEST_Data.PassengersInfo s4 WHERE s4.Line = 4AND s4.DateOfData = s.DateOfData) as Line4, 
(SELECTMAX(s5.Passengers) FROM MLTEST_Data.PassengersInfo s5 WHERE s5.Line = 5AND s5.DateOfData = s.DateOfData) as Line5,
(SELECTMAX(s6.Passengers) FROM MLTEST_Data.PassengersInfo s6 WHERE s6.Line = 6AND s6.DateOfData = s.DateOfData) as Line6, 
(SELECTMAX(s7.Passengers) FROM MLTEST_Data.PassengersInfo s7 WHERE s7.Line = 7AND s7.DateOfData = s.DateOfData) as Line7, 
(SELECTMAX(s8.Passengers) FROM MLTEST_Data.PassengersInfo s8 WHERE s8.Line = 8AND s8.DateOfData = s.DateOfData) as Line8, 
(SELECTMAX(s9.Passengers) FROM MLTEST_Data.PassengersInfo s9 WHERE s9.Line = 9AND s9.DateOfData = s.DateOfData) as Line9, 
(SELECTMAX(s10.Passengers) FROM MLTEST_Data.PassengersInfo s10 WHERE s10.Line = 10AND s10.DateOfData = s.DateOfData) as Line10 
FROM MLTEST_Data.PassengersInfo s GROUPBY DateOfData
  1. Nous créons notre modèle de type TIME SERIES (séries chronologiques), en définissant les valeurs à prédire et la colonne contenant les séries chronologiques de type DateTime (DateOfData) :
CREATETIME SERIES MODEL PassengersPrediction 
PREDICTING (Line1,Line2,Line3,Line4,Line5,Line6,Line7,Line8,Line9,Line10) 
BY (DateOfData) 
FROM MLTEST_Data.PassengersLine USING {"Forward":3}
  1. Nous formons notre modèle :
TRAIN MODEL PassengersPrediction
  1. Enfin, nous appelons l'opération métier PredictionToCSV qui générera la prédiction et l'enregistrera dans un fichier CSV.

PredictionToCSV

Cette opération métier est extrêmement simple et tout cela grâce au projet @Evgeny Shvarovcsvgen qui nous permet d'exporter directement les résultats d'une requête SQL vers un fichier CSV de manière directe. Le code de cette BO se trouve ici :

Class MLTEST.BO.PredictionToCSV Extends Ens.BusinessOperation
{

Parameter INVOCATION = "Queue";
Method ExportPrediction(pRequest As Ens.Request, pResponse As Ens.Response) As%Status
{
    set query="SELECT WITH PREDICTIONS (PassengersPrediction) * FROM MLTEST_Data.PassengersLine"w##class(community.csvgen).SQLToCSV(",",1,"/shared/prediction.csv",query)

    Quit$$$OK
}

XData MessageMap
{
<MapItems>
  <MapItem MessageType="Ens.Request">
    <Method>ExportPrediction</Method>
  </MapItem>
</MapItems>
}

}

Comme vous pouvez le constater, la requête permettant d'obtenir la prédiction est très simple.

SELECTWITH PREDICTIONS (PassengersPrediction) * FROM MLTEST_Data.PassengersLine

Voyons le résultat généré dans le fichier /shared/prediction.csv.

Conclusions

Comme vous pouvez le constater, la création de modèles de prédiction de séries temporelles est relativement simple, vous devez juste vous assurer que la colonne de type DateTime est correctement ordonnée afin que l'entraînement fonctionne sans problème.

Si vous avez des remarques ou des suggestions, n'hésitez pas à les laisser dans la section des commentaires. Merci beaucoup pour le temps accordé !

0
0 76
Article Guillaume Rongier · Mai 8, 2023 9m read

Bonjour à la communauté,
Dans cet article, je vais présenter mon application iris-mlm-explainer

Cette application web se connecte au service SQL d'InterSystems Cloud pour créer, entraîner, valider et prédire des modèles d'apprentissage automatique, faire des Prédictions et afficher un tableau de bord de tous les modèles entraînés avec une explication du fonctionnement d'un modèle d'apprentissage automatique ajusté. Le tableau de bord fournit des graphiques interactifs sur les performances du modèle, les importances des caractéristiques, les contributions des caractéristiques aux prédictions individuelles, les graphiques de dépendance partielle, les valeurs SHAP (interaction), la visualisation des arbres de décision individuels, etc.

Conditions préalables

  • Vous devez avoir un compte à SQL d'InterSystems Cloud
  • Vous devez avoir <a book="" fr="" getting-started-installing-git="" git-scm.com="" https:="" v2="">Git</a> installé localement.
  • Vous devez avoir <a downloads="" https:="" www.python.org="">Python3</a> installé localement.  

Démarrage

Nous allons suivre les étapes suivantes pour créer et afficher le tableau de bord explicatif d'un modèle :

  • Etape 1 : Fermeture/git pull du référentiel

  • Étape 2 : Connexion au portail de service SQL d'InterSystems Cloud

    • Étape 2.1 : Ajout et gestion de fichiers
    • Étape 2.2 : Importation des fichiers DDL et des fichiers de données
    • Étape 2.3 : Création du modèle
    • Étape 2.4 : Entraînement du modèle
    • Étape 2.5 : Validation du modèle
    • Étape 3 : Activation de l'environnement virtuel Python
  • Étape 4 : Exécution de l'application Web pour la prédiction

  • Étape 5 : Exploration du tableau de bord explicatif

Etape 1 : Fermeture/git Extraction du référentiel

Commençons donc par la première étape

Créer un dossier et Cloner/utiliser le git pull pour le référentiel dans n'importe quel répertoire local.

git clone https://github.com/mwaseem75/iris-mlm-explainer.git

 

Étape 2 : Connexion au portail de service SQL d'InterSystems Cloud

Connectez-vous au portail InterSystems Cloud Service Portal
image

 

 

Sélectionner le déploiement en cours

image

 

Étape 2.1 : Ajout et gestion des fichiers

Cliquez sur Ajout et gestion de fichiers (Add and Manage Files)

image

Le référentiel contient les fichiers USA_Housing_tables_DDL.sql(DDL pour créer les tables), USA_Housing_train.csv(données d'entraînement), et USA_Housing_validate.csv(pour la validation) dans le dossier datasets. Sélectionnez le bouton de téléchargement pour ajouter ces fichiers.

AddFiles

Étape 2.2 : Importation des fichiers DDL et des fichiers de données

Cliquez sur Importation de fichiers, puis sur le bouton radio Instruction(s) DDL ou DML, puis sur le bouton suivant.

ImportDDL

Cliquez sur le bouton radio Intersystems IRIS et cliquez ensuite sur le bouton suivant

IsIRIS

Sélectionnez le fichier USA_Housing_tables_DDL.sql et appuyez sur le bouton d'importation de fichiers.

ImportFileDDL

Cliquez sur le bouton d'importation "Import" dans la boîte de dialogue de confirmation pour créer le tableau.

importconfirm

###importDone

Cliquez sur le bouton des outils de requête SQL (SQL Query tools) pour vérifier que les tableaux sont créés.

###checkTblCreated

Importez des fichiers de données

Cliquez sur Importation de fichiers (Import files), puis sur le bouton radio Données CSV (CSV data), et enfin sur le bouton suivant.

csv1

Selectionnez le fichier USA_Housing_train.csv et cliquez sur le bouton suivant

###csv2

 

Sélectionnez le fichier USA_Housing_train.csv dans la liste déroulante, cochez les cases d'importation de lignes en tant que ligne d'en-tête et de noms de champs dans la ligne d'en-tête correspondant aux noms de colonnes dans le tableau sélectionné, puis cliquez sur Importation de fichiers.

csv3

cliquer sur "importation" dans la boîte de dialogue de confirmation

csv4

Assurez-vous que 4000 lignes sont mises à jour

csv5

Procédez de la même manière pour importer le fichier USA_Housing_validate.csv qui contient 1500 enregistrements.

csv6

Étape 2.3 : Création du modèle

Cliquez sur les outils IntegratedM et sélectionnez Créer un panneau (Create Panel).

Saisissez USAHousingPriceModel dans le champ de nom du modèle (Model Name), sélectionnez le tableau usa_housing_train et Prix dans la liste déroulante des champs à prédire (Field to predict). Cliquez sur le bouton "Création du modèle" pour créer le modèle.

createModel

 

Étape 2.4 : Entraînement du modèle

sélectionnez le panneau d'entraînement (Train Panel), sélectionnez USAHousingPriceModel dans la liste déroulante du modèle à entraîner et saisissez USAHousingPriceModel_t1 dans le champ du nom du modèle d'entraînement (Train Model Name)

###TRAIN1

Le modèle sera entraîné une fois l'état de fonctionnement (Run Status) achevé

###TRAIN2

 

Étape 2.5 : Validation du modèle

Sélectionnez le panneau de validation (Validate Panel), sélectionnez USAHousingPriceModel_t1 dans le modèle entraîné pour valider la liste déroulante, sélectionnez usa_houseing_validate dans le tableau pour valider le modèle à partir de la liste déroulante et cliquez sur le bouton de validation du modèle.

###image

Cliquez sur affichage des mesures de validation pour visualiser les mesures.

showValidation

Cliquez sur l'icône graphique pour afficher le graphique Prédiction VS Réalité.

validationChart

 

Étape 3 : Activation de l'environnement virtuel Python

Le référentiel contient déjà un dossier d'environnement virtuel python (venv) avec toutes les bibliothèques nécessaires.

Il suffit d'activer l'environnement
Pour Unix ou MacOS :

&lt;span class="hljs-meta">$&lt;/span>&lt;span class="bash"> &lt;span class="hljs-built_in">source&lt;/span> venv/bin/activate&lt;/span>

Pour Windows:

venv\scripts\activate

Étape 4 : Définir les paramètres de connexion à InterSystems SQL Cloud

Le référentiel contient le fichier config.py. Il suffit de l'ouvrir et de le paramétrer
image
Mettez les mêmes valeurs que celles utilisées dans InterSystems SQL Cloud
image

 

Étape 4 : Exécution de l'application Web pour la prédiction

Exécutez la commande suivante dans l'environnement virtuel pour démarrer notre application principale

python app.py

###image

Pour démarrer l'application, naviguez jusqu'à http://127.0.0.1:5000/

image

Entrez l'âge de la maison, le nombre de pièces, le nombre de chambres et la population de la région pour obtenir la prédiction

image

Étape 5 : Exploration du tableau de bord explicatif

Enfin, exécutez la commande suivante dans l'environnement virtuel pour démarrer notre application principale

python expdash.py

imageimage
image

Pour démarrer l'application, naviguez jusqu'à http://localhost:8050/image

L'application répertorie tous les modèles entraînés ainsi que notre modèle USAHousingPriceModel. Cliquez sur "aller au panneau de bord" ("go to dashboard") pour voir l'explication du modèle.

Importance des fonctionnalités. Quelles sont les fonctionnalités ayant eu l'impact le plus important ?
image

Mesures quantitatives de la performance des modèles : dans quelle mesure la valeur prédite est-elle proche de la valeur observée ?
image

Prédiction et Comment chaque fonctionnalité a-t-elle contribué à la prédiction ?
image

Ajustez les valeurs des fonctionnalités pour modifier la prédiction
image

Sommaire des SHAPs, Classement des caractéristiques par valeurs de SHAPs
image

Sommaire des interactions, classement des fonctionnalités par valeur d'interaction de SHAP
image

Arbres de décision, affichage des arbres de décision individuels dans la forêt aléatoire
image

Merci

0
0 47
Article Lucas Enard · Sept 30, 2022 9m read

Dans ce GitHub nous recueillons des informations à partir d'un csv, nous utilisons une DataTransformation pour les transformer en un objet FHIR, puis nous sauvegardons ces informations sur un serveur FHIR, et tout cela en utilisant uniquement Python.

The objective is to show how easy it is to manipulate data into the output we want, here a FHIR Bundle, in the IRIS full Python framework.

1. Fhir-orga-dt

2. Préalables

Assurez-vous que git et Docker desktop sont installé.

Si vous travaillez à l'intérieur du conteneur, comme il est montré dans 3.3., vous n'avez pas besoin d'installer fhirpy et fhir.resources.

Si vous n'êtes pas dans le conteneur, vous pouvez utiliser pip pour installer fhirpy et fhir.resources.
Vérifiez fhirpy et fhir.resources pour plus d'information.

3. Installation

3.1. Installation pour le développement

Clone/git tire le repo dans n'importe quel répertoire local, par exemple comme indiqué ci-dessous :

git clone https://github.com/LucasEnard/fhir-client-python.git

Ouvrez le terminal dans ce répertoire et lancez :

docker build .

3.2. Portail de gestion et VSCode

Ce référentiel est prêt pour VS Code.

Ouvrez le dossier fhir-client-python cloné localement dans VS Code.

Si vous y êtes invité (coin inférieur droit), installez les extensions recommandées.

3.3. Avoir le dossier ouvert à l'intérieur du conteneur

Vous pouvez être à l'intérieur du conteneur avant de coder si vous le souhaitez.
Pour cela, il faut que docker soit activé avant d'ouvrir VSCode.
Ensuite, dans VSCode, lorsque vous y êtes invité ( coin inférieur droit ), rouvrez le dossier à l'intérieur du conteneur afin de pouvoir utiliser les composants python qu'il contient.
La première fois que vous effectuez cette opération, cela peut prendre plusieurs minutes, le temps que le conteneur soit préparé.

Si vous n'avez pas cette option, vous pouvez cliquer dans le coin inférieur gauche et cliquer sur Ouvrir à nouveau dans le conteneur puis sélectionner De Dockerfile

Plus d'informations ici

Architecture


En ouvrant le dossier à distance, vous permettez à VS Code et à tous les terminaux que vous ouvrez dans ce dossier d'utiliser les composants python dans le conteneur.

4. Serveur FHIR

Pour compléter cette présentation, nous allons utiliser un serveur fhir.
Ce serveur fhir était déjà intégré lorsque vous avez cloné et construit le conteneur.

L'url est localhost:52773/fhir/r4

5. Présentation pas à pas

Présentation complète de la réalisation d'IRIS en Python.

5.1. Messages and objects

Les objets et les messages contiennent les informations entre nos services, nos processus et nos opérations.

Dans le fichier obj.py nous devons créer une classe de données qui correspond au csv, ceci sera utilisé pour garder l'information avant de faire la DataTransformation.
Dans notre exemple, le csv organisation.csv ressemble à ceci,

active;name;city;country;system;value
true;Name1;city1;country1;phone;050678504
false;Name2;city2;country2;phone;123456789

Par conséquent, l'objet ressemblera à ceci,

@dataclass
# > Cette classe représente une organisation simple
class BaseOrganization:
    active:bool = None
    name:str = None
    city:str = None
    country:str = None
    system:str = None
    value:str = None

Dans le fichier msg.py, nous aurons deux types de requêtes, la première contenant les informations d'une organisation avant la DataTransformation et la seconde contenant les informations de l'organisation après la DataTransformation.

5.2. Service aux entreprises

Dans le fichier bs.py, nous avons le code qui nous permet de lire le csv et pour chaque ligne du csv (donc pour chaque organisation), le mapper dans un objet que nous avons créé plus tôt. Ensuite, pour chacune de ces lignes (organisation), nous créons une requête et l'envoyons à notre processus pour effectuer la DataTransformation.

# Nous ouvrons le fichier
with open(self.path + self.filename,encoding="utf-8") as csv:
    # Nous le lisons et le mappons en utilisant l'objet BaseOrganization précédemment utilisé
    reader = DataclassReader(csv, self.fhir_type ,delimiter=";")
    # Pour chacune de ces organisations, nous pouvons créer une requête et l'envoyer au processus
    for row in reader:
        msg = OrgaRequest()
        msg.organization = row
        self.send_request_sync('Python.ProcessCSV',msg)

5.3. Service aux entreprises

Dans le fichier bp.py, nous avons la DataTransformation, qui convertit un simple objet python contenant peu d'informations en un objet FHIR R4

Voici les étapes pour effectuer une DataTransformation en utilisant du python embarqué sur notre organisation simple,

# Création de l'objet Organisation
organisation = Organisation()

# Mappage des informations de la demande à l'objet Organisation
organization.name = base_orga.name

organization.active = base_orga.active

## Création de l'objet Adresse et mappage des informations
## de la demande à l'objet Addresse
adresse = Addresse()
adress.country = base_orga.country
adress.city = base_orga.city

### Configuration de l'adresse de notre organisation à celle que nous avons créée
organization.address = [adress]

## Création de l'objet ContactPoint et mise en correspondance
## des informations de la demande avec l'objet ContactPoint
telecom = ContactPoint()
telecom.value = base_orga.value
telecom.system = base_orga.system

### Configuration de la télécommunication de notre organisation à celle que nous avons créée
organization.telecom = [telecom]

# Maintenant, notre DT est achevé, nous avons une organisation d'objets qui est
# un objet FHIR R4 et qui contient toutes nos informations csv.

Après cela, notre mappage est terminé et notre DT fonctionne.
Maintenant, nous pouvons envoyer cette ressource FHIR R4 nouvellement créée à notre FhirClient qui est notre opération.

5.4. Opération d'un entreprise

Dans le fichier bo.py nous avons le FhirClient, ce client crée une connexion à un serveur fhir qui contiendra les informations recueillies par le csv.

Dans cet exemple, nous utilisons un serveur fhir local qui n'a pas besoin d'une clé api pour se connecter.
Pour s'y connecter, nous devons utiliser la fonction on_init,

if not hasattr(self,'url'):
    self.url = 'localhost:52773/fhir/r4'

self.client = SyncFHIRClient(url=self.url)

Maintenant, lorsque nous recevons un message/demande, nous pouvons, en trouvant le type de ressource de la ressource que nous envoyons avec notre demande au client, créer un objet lisible par le client, puis le sauvegarder sur le serveur fhir.

# Obtenez le type de ressource de la demande ( ici "Organisation" )
resource_type = request.resource["resource_type"]

# Créer une ressource de ce type en utilisant les données de la demande
resource = construct_fhir_element(resource_type, request.resource)

# Sauvegarder la ressource sur le serveur FHIR en utilisant le client
self.client.resource(resource_type,**json.loads(resource.json())).save()

Il est à noter que le client fhir fonctionne avec n'importe quelle ressource de FHIR R4 et pour utiliser et modifier notre exemple, nous devons seulement changer la DataTransformation et l'objet qui contient les informations csv.

5.5. Conclusion de la présentation

Si vous avez suivi ce parcours, vous savez maintenant exactement comment lire un csv d'une représentation d'une ressource FHIR R4, utiliser une DataTransformation pour le transformer en un véritable objet FHIR R4 et le sauvegarder sur un serveur.

6. Création d'une nouvelle DataTransformation

Ce référentiel est prêt à être codé en VSCode avec les plugins InterSystems. Ouvrez /src/python pour commencer à coder ou utiliser l'autocomplétion.

Étapes pour créer une nouvelle transformation
Pour ajouter une nouvelle transformation et l'utiliser, la seule chose que vous devez faire est d'ajouter votre csv nommé Patient.csv (par exemple) dans le dossier src/python/csv.
Ensuite, créez un objet dans src/python/obj.py appelé BasePatient qui met en correspondance votre csv.
Maintenant, créez une requête dans src/python/msg.py appelée PatientRequest qui a une variable resource de type BasePatient.
L'étape finale est la DataTransformation, pour cela, allez dans src/python/bp.py et ajoutez votre DT. Ajoutez d'abord if isinstance(request, PatientRequest): puis mappez votre ressource de requête à une fhir.resource Patient.
Maintenant si vous allez dans le portail de gestion et changez le paramètre du ServiceCSV pour ajouter filename=Patient.csv vous pouvez juste démarrer la réalisation et voir votre transformation se dérouler et votre client envoyer les informations au serveur.

Étapes détaillées pour créer une nouvelle transformation
Si vous n'êtes pas sûr de ce qu'il faut faire ou de la manière de le faire, voici une création étape par étape d'une nouvelle transformation :

Créez le fichier Patient.csv and le dossier src/python/csv pour les remplir avec le suivant:

family;given;system;value
FamilyName1;GivenName1;phone;555789675
FamilyName2;GivenName2;phone;023020202

Notre CSV contient un nom de famille, un prénom et un numéro de téléphone pour deux patients.


Dans src/python/obj.py écrivez :

@dataclass
class BasePatient:
    family:str = None
    given:str = None
    system:str = None
    value:str = None


Dans src/python/msg.py écrivez :

from obj import BasePatient
@dataclass
class PatientRequest(Message):
    resource:BasePatient = None


Dans src/python/bp.py écrivez :

from msg import PatientRequest
from fhir.resources.patient import Patient
from fhir.resources.humanname import HumanName

Dans src/python/bp.py dans la fonction on_request écrivez :

if isinstance(request,PatientRequest):
    base_patient = request.resource

    patient = Patient()

    name = HumanName()
    name.family = base_patient.family
    name.given = [base_patient.given]
    patient.name = [name]

    telecom = ContactPoint()
    telecom.value = base_patient.value
    telecom.system = base_patient.system
    patient.telecom = [telecom]

    msg = FhirRequest()
    msg.resource = patient

    self.send_request_sync("Python.FhirClient", msg)


Maintenant si vous allez dans le portail de gestion et changez le paramètre du ServiceCSV pour ajouter filename=Patient.csv vous pouvez juste arrêter et redémarrer la production et voir votre transformation se dérouler et votre client envoyer les informations au serveur.

Settings

7. Ce qu'il y a dans le référentiel

7.1. Dockerfile

Le dockerfile le plus simple pour démarrer un conteneur Python.
Utilisez docker build . pour construire et rouvrir votre fichier dans le conteneur pour travailler à l'intérieur de celui-ci.

7.2. .vscode/settings.json

Fichier de paramètres.

7.3. .vscode/launch.json

Fichier de configuration si vous voulez déboguer.

0
0 126
Article Lorenzo Scalese · Mai 12, 2022 8m read

IRIS External Table est un projet Open Source de la communauté InterSystems, qui vous permet d'utiliser des fichiers stockés dans le système de fichiers local et le stockage d'objets en nuage comme AWS S3, en tant que tables SQL. IRIS External Table

Il peut être trouvé sur Github https://github.com/intersystems-community/IRIS-ExternalTable Open Exchange https://openexchange.intersystems.com/package/IRIS-External-Table et est inclus dans InterSystems Package Manager ZPM.

Pour installer External Table depuis GitHub, utilisez :

git clone https://github.com/antonum/IRIS-ExternalTable.git
iris session iris
USER>set sc = ##class(%SYSTEM.OBJ).LoadDir("<path-to>/IRIS-ExternalTable/src", "ck",,1)

Pour installer avec ZPM Package Manager, utilisez :

USER>zpm "install external-table"

Travailler avec des fichiers locaux

Créons un fichier simple qui ressemble à ceci :

a1,b1
a2,b2

Ouvrez votre éditeur préféré et créez le fichier ou utilisez simplement une ligne de commande sous linux/mac :

echo $'a1,b1\na2,b2' > /tmp/test.txt

Dans IRIS SQL, créez une table pour représenter ce fichier :

create table test (col1 char(10),col2 char(10))

Convertissez la table pour utiliser le stockage externe :

CALL EXT.ConvertToExternal(
    'test',
    '{
        "adapter":"EXT.LocalFile",
        "location":"/tmp/test.txt",
        "delimiter": ","
    }')

Et enfin - interrogez la table :

select * from test

Si tout fonctionne comme prévu, vous devriez voir un résultat comme celui-ci :

col1	col2
a1	b1
a2	b2

Retournez maintenant dans l'éditeur, modifiez le contenu du fichier et réexécutez la requête SQL. Ta-Da !!! Vous lisez les nouvelles valeurs de votre fichier local en SQL.

col1	col2
a1	b1
a2	b99

Lecture de données à partir de S3

Sur <https://covid19-lake.s3.amazonaws.com/index.html >, vous pouvez avoir accès à des données constamment mises à jour sur le COVID, stockées par AWS dans la réserve publique de données.

Essayons d'accéder à l'une des sources de données de cette réserve de données : s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states

Si vous avez installé l'outil de ligne de commande AWS, vous pouvez répéter les étapes ci-dessous. Sinon, passez directement à la partie SQL. Vous n'avez pas besoin d'installer quoi que ce soit de spécifique à AWS sur votre machine pour suivre la partie SQL.

$ aws s3 ls s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/
2020-12-04 17:19:10     510572 us-states.csv

$ aws s3 cp s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv .
download: s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv to ./us-states.csv

$ head us-states.csv
date,state,fips,cases,deaths
2020-01-21,Washington,53,1,0
2020-01-22,Washington,53,1,0
2020-01-23,Washington,53,1,0
2020-01-24,Illinois,17,1,0
2020-01-24,Washington,53,1,0
2020-01-25,California,06,1,0
2020-01-25,Illinois,17,1,0
2020-01-25,Washington,53,1,0
2020-01-26,Arizona,04,1,0

Nous avons donc un fichier avec une structure assez simple. Cinq champs délimités.

Pour exposer ce dossier S3 en tant que table externe - d'abord, nous devons créer une table "normal" avec la structure désirée :

-- create external table
create table covid_by_state (
    "date" DATE,
    "state" VARCHAR(20),
    fips INT,
    cases INT,
    deaths INT
)


Notez que certains noms de champs comme "Date" sont des mots réservés dans IRIS SQL et doivent être entourés de guillemets doubles.
Ensuite - nous devons convertir cette table "régulière" en table "externe", basé sur le godet AWS S3 et le type de CSV.

 -- convertissez le tableau en stockage externe
call EXT.ConvertToExternal(
    'covid_by_state',
    '{
    "adapter":"EXT.AWSS3",
    "location":"s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/",
    "type": "csv",
    "delimiter": ",",
    "skipHeaders": 1
    }'
)

Si vous regardez de près - les arguments des procédures EXT.ExternalTable sont le nom de la table et ensuite une chaîne JSON, contenant plusieurs paramètres, tels que l'emplacement pour rechercher les fichiers, l'adaptateur à utiliser, le délimiteur, etc. En plus de AWS S3 External Table supporte le stockage Azure BLOB, Google Cloud Buckets et le système de fichiers local. GitHub Repo contient des références pour la syntaxe et les options supportées pour tous les formats.

Et enfin - faites une requête sur le tableau :

-- faites une requête sur le tableau :
select top 10 * from covid_by_state order by "date" desc

[SQL]USER>>select top 10 * from covid_by_state order by "date" desc
2.	select top 10 * from covid_by_state order by "date" desc

date	état	fips	cas	morts
2020-12-06	Alabama	01	269877	3889
2020-12-06	Alaska	02	36847	136
2020-12-06	Arizona	04	364276	6950
2020-12-06	Arkansas	05	170924	2660
2020-12-06	California	06	1371940	19937
2020-12-06	Colorado	08	262460	3437
2020-12-06	Connecticut	09	127715	5146
2020-12-06	Delaware	10	39912	793
2020-12-06	District of Columbia	11	23136	697
2020-12-06	Florida	12	1058066	19176

L'interrogation des données de la tableau distant prend naturellement plus de temps que celle de la table "IRIS natif" ou global, mais ces données sont entièrement stockées et mises à jour sur le nuage et sont introduites dans IRIS en coulisse.

Explorons quelques autres caractéristiques de la table externe.

%PATH et tables, sur la base de plusieurs fichiers

Dans notre exemple, le dossier du godet ne contient qu'un seul fichier. Le plus souvent, il contient plusieurs fichiers de la même structure, où le nom de fichier identifie soit l'horodatage, soit le numéro de périphérique, soit un autre attribut que nous voulons utiliser dans nos requêtes.

Le champ %PATH est automatiquement ajouté à chaque table externe et contient le chemin d'accès complet au fichier à partir duquel la ligne a été récupérée.

select top 5 %PATH, * from covid_by_state

%PATH	date	state	fips	cases	deaths
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv	2020-01-21	Washington	53	1	0
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv	2020-01-22	Washington	53	1	0
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv	2020-01-23	Washington	53	1	0
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv	2020-01-24	Illinois	17	1	0
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv	2020-01-24	Washington	53	1	0

Vous pouvez utiliser ce champ %PATH dans vos requêtes SQL comme n'importe quel autre champ.

Données ETL vers des " tables réguliers "

Si votre tâche consiste à charger des données de S3 dans une table IRIS - vous pouvez utiliser l'External Table comme un outil ETL. Il suffit de le faire :

INSERT INTO internal_table SELECT * FROM external_table

Dans notre cas, si nous voulons copier les données COVID de S3 dans la table local :

--create local table
create table covid_by_state_local (
    "date" DATE,
    "state" VARCHAR(100),
    fips INT,
    cases INT,
    deaths INT
)
--ETL from External to Local table
INSERT INTO covid_by_state_local SELECT TO_DATE("date",'YYYY-MM-DD'),state,fips,cases,deaths FROM covid_by_state

JOIN entre IRIS tables natif et External Table. Requêtes fédérées

External Table est une table SQL. Il peut être joint à d'autres tables, utilisé dans des sous-sélections et des UNIONs. Vous pouvez même combiner la table IRIS "Régulier" et deux ou plusieurs tables externes provenant de sources différentes dans la même requête SQL.

Essayez de créer une table régulier, par exemple en faisant correspondre les noms d'État aux codes d'État, comme Washington - WA. Et joignez-la à notre table basé sur S3.

create table state_codes (name varchar(100), code char(2))
insert into state_codes values ('Washington','WA')
insert into state_codes values ('Illinois','IL')

select top 10 "date", state, code, cases from covid_by_state join state_codes on state=name

Remplacez 'join' par 'left join' pour inclure les lignes pour lesquelles le code d'état n'est pas défini. Comme vous pouvez le constater, le résultat est une combinaison de données provenant de S3 et de votre table IRIS natif.

Accès sécurisé aux données

La réserve de données AWS Covid est publique. N'importe qui peut y lire des données sans aucune authentification ou autorisation. Dans la vie réelle, vous souhaitez accéder à vos données de manière sécurisée, afin d'empêcher les étrangers de jeter un coup d'œil à vos fichiers. Les détails complets de la gestion des identités et des accès (IAM) d'AWS n'entrent pas dans le cadre de cet article. Mais le minimum, vous devez savoir que vous avez besoin au moins de la clé d'accès au compte AWS et du secret afin d'accéder aux données privées de votre compte. <https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys >

AWS utilise l'authentification par clé de compte/secrète autentification pour signer les demandes. https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys

Si vous exécutez IRIS External Table sur une instance EC2, la méthode recommandée pour gérer l'authentification est d'utiliser les rôles d'instance EC2 https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html IRIS External Table sera en mesure d'utiliser les permissions de ce rôle. Aucune configuration supplémentaire n'est requise.

Sur une instance locale/non EC2, vous devez spécifier AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY en spécifiant des variables d'environnement ou en installant et en configurant le client AWS CLI.

export AWS_ACCESS_KEY_ID=AKIAEXAMPLEKEY
export AWS_SECRET_ACCESS_KEY=111222333abcdefghigklmnopqrst

Assurez-vous que la variable d'environnement est visible dans votre processus IRIS. Vous pouvez le vérifier en exécutant :

USER>write $system.Util.GetEnviron("AWS_ACCESS_KEY_ID")

Il doit renvoi la valeur de clé.

ou installer AWS CLI, en suivant les instructions ici https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html et exécuter :

aws configure

External Table sera alors en mesure de lire les informations d'identification à partir des fichiers de configuration aws cli. Votre shell interactif et votre processus IRIS peuvent être exécutés sous différents comptes - assurez-vous d'exécuter aws configure sous le même compte que votre processus IRIS.

0
0 92