Article
· Fév 7 8m de lecture

A propos de l'idée d'utiliser la syntaxe de définition de classe de Python pour créer des classes IRIS

Introduction

Il n'y a pas si longtemps, j'ai vu l'idée de using Python Class Definition Syntax to create IRIS classes

sur le portail d'idées d'InterSystems. Elle a attiré mon attention car l'intégration d'un maximum de syntaxes donne de la visibilité aux produits d'InterSystems pour les programmeurs ayant de l'expérience dans de nombreux langages.

L'auteur de cette idée a souligné la possibilité de créer des classes en utilisant la syntaxe de Python, en plus de celles actuellement disponibles sur IRIS. Cette idée m'a incité à écrire cet article, qui explore les possibilités d'accéder à toute la puissance d'InterSystems en utilisant uniquement Python.

Il convient de noter que l'un des précurseurs de toute cette puissance est la capacité multi-modèle d'IRIS. Elle vous permet d'accéder aux mêmes données par le biais de globaux (une structure de stockage multidimensionnelle). Il s'agit également de la structure sous-jacente pour tous les autres modèles. De même, vous pouvez accéder aux données susmentionnées par le biais d'objets. Dans le cadre de cet article, l'accès aux données par objet signifie l'utilisation d'adaptateurs JSON ou XML pour connecter IRIS et Python. Par ailleurs, vous pouvez accéder aux données par SQL en utilisant des connexions JDBC ou ODBC. Enfin, vous pouvez utiliser DocDB (Document database) qui utilise également la syntaxe JSON pour obtenir le même résultat.

Créer une base de données IRIS à partir d'une classe Python en utilisant SQL

Pour commencer, nous devrions discuter du point principal de l'idée : comment utiliser la syntaxe de définition de classe de Python pour créer une classe IRIS. Il est possible d'y parvenir, mais la complexité de cette implémentation dépendra entièrement de la sophistication des relations définies dans votre classe. Vous pouvez cliquer sur ici pour consulter mes études sur cette solution. N'hésitez pas à me contacter si vous souhaitez en discuter davantage !

Si vous n'avez besoin que des propriétés d'une classe définie en Python, l'approche la plus simple sera d'utiliser la fonction mapper() de SQLAlchemy pour créer votre classe.

Pour ce faire, vous aurez besoin des importations suivantes :

from sqlalchemy import create_engine, MetaData
from sqlalchemy.schema import Table, Column
from sqlalchemy.orm import mapper

Bien entendu, vous devez commencer par définir votre moteur, et ensuite seulement créer votre table. En option, vous pouvez définir une colonne de clé primaire si votre classe n'en dispose pas déjà.

engine = create_engine("iris://" + user + ":" + password + "@" + host + ":" + port + "/" + namespace)
metadata = MetaData()
table = Table(class_name, metadata, Column('id', Integer,  primary_key = True))

De plus, pour chaque propriété de votre classe, n'oubliez pas d'ajouter une Column() dans votre table avec son nom, le type SQL de sqlalchemy.sql.sqltypes, et éventuellement une valeur par défaut. Vous pouvez consulter ce lien très utile avec un dictionnaire Python-SQL pour vous simplifier la tâche.

Enfin, vous devez appeler le mappeur avec votre classe et la table comme arguments, et les créer avec votre moteur.

mapper(my_class, table)
metadata.create_all(engine)

Si vous souhaitez néanmoins développer des méthodes, vous pouvez accéder à votre fichier .cls nouvellement créé, définir une méthode avec une définition ObjectScript et lui attribuer le langage Python.

Cependant, vous pouvez toujours éviter cette seule ligne d'ObjectScript lors de la création de votre classe. La façon de le faire est d'utiliser InterSystems Native SDK for Python pour connecter Python à Iris et l'utiliser pour accéder aux classes %Dictionary.

Ces classes vous aideront à construire votre fichier .cls. Vous aurez besoin d'un schéma, d'un nom de classe, de noms et de types de propriétés, ainsi que d'implémentations de méthodes pour accomplir cette tâche.

Si vous avez une classe définie en Python, vous pouvez facilement accéder à ces informations. Définissez le schéma comme vous le souhaitez et accédez au nom de la classe en une ligne de code, comme indiqué ci-dessous :

class_name = your_class.__class__.__name__

Ensuite, la fonction intégrée dir() vous donnera tous les attributs d'une classe. Vous pouvez utiliser la méthode callable() pour vérifier s'il s'agit d'une propriété ou d'une méthode. Enfin, vous pouvez importer le module inspect et utiliser ses fonctions getsource() et getfullargspec() pour accéder à toutes les informations de vos méthodes.

implementation = i.getsource(function) # this gets the written code as a string
inspection = i.getfullargspec(function) 
defaults = inspection.defaults
annotation = inspection.annotations
arguments = inspection[0]

Gardez à l'esprit que si le premier argument d'une fonction de classe de Python est "self", elle est représentée dans ObjectScript comme une méthode. Sinon, elle sera représentée comme une ClassMethod.

Avec ces éléments, vous pouvez ouvrir votre classe et la modifier avec les classes %Dictionary.

new_class = irispy.classMethodObject("%Dictionary.ClassDefinition", "%Open", class_name)
new_method = irispy.classMethodObject("%Dictionary.MethodDefinition", "%New", class_name + ":" + method_name)
new_method.set("Language", "python")
new_method.get("Implementation").invoke("Write", implementation)
new_method.set("ClassMethod", isClassMethod)
new_method.set("FormalSpec", formal_spec)
new_class.get("Methods").invoke("Insert", new_method)

Dans le code ci-dessus, l'objet irispy a été généré en connectant l'instance IRIS avec la méthode createIRIS() du module IRIS. Vous trouverez plus de détails sur l'établissement de la connexion dans la documentation officielle ou dans l'un de mes articles précédents. Cependant, pour l'instant, le code illustré ci-dessous est tout ce que vous avez besoin de savoir :

import iris

# Open a connection to the server
args = {'hostname':'127.0.0.1', 'port':52773,
    'namespace':'USER', 'username':'_SYSTEM', 'password':'SYS'
}
conn = iris.connect(**args)
# Create an iris object
irispy = iris.createIRIS(conn)

Vous pouvez créer votre formal_spec avec l'annotation de l'inspection.

Pour la dernière étape, n'oubliez pas d'invoquer %Save sur cette définition.

sc = new_class.invoke("%Save")

 

Créer une base de données IRIS à partir d'une classe Python en utilisant DocDB

Tout d'abord, vous devez permettre à votre instance de recevoir ce type de requête REST. Pour ce faire, allez dans Administration du système > Sécurité > Service, sélectionnez %Service_DocDB, choisissez "Service activé" et cliquez sur enregistrer. Ensuite, votre système peut nécessiter l'installation du module de requêtes Python avec pip install requests. 

Si vous n'êtes pas familier avec les API REST en Python, vous pourrez quand même suivre ce tutoriel car tout ce qui sera utilisé ici est assez intuitif.

Nous n'aurons besoin que d'envoyer quelques URL à %Api.DocDB.v1, qui est une option intégrée dans IRIS. Il suffit d'importer requests dans votre environnement Python et d'écrire une URL avec le modèle démontré ci-dessous :

url = http://HOST:PORT/api/docdb/v1/NAMESPACE/db/DBNAME?type=cls

Ensuite, envoyez une requête POST à cette URL avec request.post(url). Vous êtes prêt ! Vous devriez maintenant pouvoir voir une classe appelée CLASSNAME dans le schéma par défaut ISC_DM, dans l'espace de noms sélectionné.


Après avoir créé la classe, vous pouvez ajouter des propriétés en envoyant d'autres requêtes POST avec le modèle d'URL suivant :

http://HOST:PORT/api/docdb/v1/NAMESPACE/prop/DBNAME/PROPERTYNAME?type=%String&path=PROPERTYPATH

Vous pouvez percevoir le chemin de la propriété comme le chemin que vous utiliseriez pour obtenir la valeur de cette propriété si elle était stockée dans un objet dynamique construit à partir de JSON. Par exemple, imaginez que vous puissiez représenter votre objet comme dans l'extrait de code ci-dessous.

{
    "person": {
        "name":"heloisa tambara",
        "country":"brazil"
    }
}

Dans ce cas, le chemin d'accès à la propriété name serait person.name.

Enfin, vous pouvez commencer à remplir cette table avec un autre modèle d'URL :

http://HOST:PORT/api/docdb/v1/NAMESPACE/doc/DBNAME/ID

Si vous souhaitez créer un nouveau document, utilisez la méthode POST et laissez le champ ID vide. En revanche, pour remplacer un document existant, utilisez la méthode PUT et indiquez l'ID que vous souhaitez modifier.

Rédigez le corps de votre requête en fonction des chemins de propriété que vous avez utilisés. Par exemple, si vous avez créé des propriétés avec les chemins "person.name", "person.location.country", "person.location.state", "person.location.city", vous pouvez ajouter un document en envoyant le JSON ci-dessous dans le corps de votre requête.

{
    "person": {
        "name":"Heloisa Tambara",
        "location": {
            "country":"Brasil",
            "state":"Pernambuco",
            "city":"Recife"
        }
    }
}

Cette section a été conçue pour vous donner un avant-goût de ce que DocDB peut faire. Dans la documentation à laquelle vous pouvez accéder en cliquant ici, vous pouvez découvrir toutes les méthodes disponibles de manière plus détaillée.

 

Aller plus loin : utiliser l'interopérabilité d'IRIS sans ObjectScript

Pour la plupart des implémentations, vous pouvez presque supprimer l'utilisation des classes COS. Supposons que vous recherchiez une production à interopérabilité totale construite uniquement avec Python. Dans ce cas, vous pouvez essayer PEX (Production EXtension framework) et limiter l'utilisation des fichiers .cls à la seule classe de production. La meilleure pratique pour utiliser PEX est d'employer l'application de Guillaume Rongier (interoperability-embedded-python), qui fait le lien entre l'architecture d'interopérabilité d'InterSystems et Python. Si vous n'êtes pas encore familiarisé avec cette structure, jetez un coup d'œil au cours de 30 minutes consacré à l'architecture d'interopérabilité d'InterSystems. Integration Architecture.

Si tel est votre objectif, je vous recommande de parcourir l'article sur les Full Python IRIS production: DataTransformation of a CSV to a FHIR server par Lucas Enard. La page GitHub relative à l'application OpenExchange décrite dans le texte est un excellent exemple de la manière dont on peut développer principalement en Python.

 

Il y a toujours plus...

Comme vous pouvez le constater, il existe de nombreuses façons de créer, de manipuler et d'alimenter les classes dans IRIS. Avez-vous déjà pris connaissance de toutes les méthodes décrites ci-dessus ? Quelles sont celles sur lesquelles vous aimeriez que j'écrive davantage ? Quelles sont les autres méthodes que vous connaissez et dont je n'ai pas encore parlé ? N'hésitez pas à me faire part de vos réflexions !

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer