Nova postagem

Pesquisar

Pergunta
· Set. 9, 2023

Compacting and Truncating very large datasets

Does anyone have experience compacting and truncating IRIS datasets that are greater than 10 TB in size?  How long did it take and what was the size?  Did you run into any issues?  

Thanks.

Diane

4 Comments
Discussão (4)1
Entre ou crie uma conta para continuar
Artigo
· Set. 4, 2023 6min de leitura

Initialisation de l'image Docker InterSystems IRIS avec Python

Lorsque nous démarrons le développement avec IRIS, nous disposons d'un kit de distribution ou, dans le cas de Docker, nous extrayons l'image Docker, puis nous devons souvent l'initialiser et configurer l'environnement de développement. Nous devrons peut-être créer des bases de données, des espaces de noms, activer/désactiver certains services, créer des ressources. Nous devons souvent importer du code et des données dans l'instance IRIS et exécuter du code personnalisé pour lancer la solution.

Il existe de nombreux modèles sur Open Exchange dans lesquels nous suggérons comment initialiser REST, l'interopérabilité, l'analytics, le développement Fullstack et bien d'autres modèles utilisant ObjectScript. Mais qu'en est-il si nous souhaitons utiliser uniquement Python pour configurer l'environnement de développement d'un projet Embedded Python avec IRIS ?

De fait, la récente sortie de Embedded Python template est devenu le passe-partout du pur Python qui pourrait être un point de départ pour les développeurs qui créent des projets Python sans avoir besoin d'utiliser et d'apprendre ObjectScript. Cet article explique comment ce modèle pourrait être utilisé pour initialiser IRIS. C'est parti!

Ok!

Création d'une base de données et d'un espace de nom

Nous devons souvent créer une base de données et un espace de noms. Cela pourrait être fait avec la fonctionnalité de fusion cpf d'IRIS, et voici le fichier de fusion qui fait la chose :

[Actions]
CreateResource:Name=%DB_IRISAPP_DATA,Description="IRISAPP_DATA database"
CreateDatabase:Name=IRISAPP_DATA,Directory=/usr/irissys/mgr/IRISAPP_DATA,Resource=%DB_IRISAPP_DATA
CreateResource:Name=%DB_IRISAPP_CODE,Description="IRISAPP_CODE database"
CreateDatabase:Name=IRISAPP_CODE,Directory=/usr/irissys/mgr/IRISAPP_CODE,Resource=%DB_IRISAPP_CODE
CreateNamespace:Name=IRISAPP,Globals=IRISAPP_DATA,Routines=IRISAPP_CODE,Interop=1
ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=48
ModifyUser:Name=SuperUser,PasswordHash=a31d24aecc0bfe560a7e45bd913ad27c667dc25a75cbfd358c451bb595b6bd52bd25c82cafaa23ca1dd30b3b4947d12d3bb0ffb2a717df29912b743a281f97c1,0a4c463a2fa1e7542b61aa48800091ab688eb0a14bebf536638f411f5454c9343b9aa6402b4694f0a89b624407a5f43f0a38fc35216bb18aab7dc41ef9f056b1,10000,SHA512

Merge cpf contient les Actions qui dans ce cas créent des base de données IRISAPP_DATA and IRISAPP_CODE respectivement pour les données et le code, l'espace de noms IRISAPP associé pour y accéder et les ressources associées %IRISAPP_DATA et %IRISAPP_CODE pour gérer les autorisations d'accès.

Ce Merge cpf permet également au service Callin de faire fonctionner Embedded Python via l'action ModifyService :

ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=48

La dernière action est un exemple de la façon dont vous pouvez définir en toute sécurité le mot de passe de l'utilisateur, à l'aide de l'action ModifyUser :

ModifyUser:Name=SuperUser,PasswordHash=a31d24aecc0bfe560a7e45bd913ad27c667dc25a75cbfd358c451bb595b6bd52bd25c82cafaa23ca1dd30b3b4947d12d3bb0ffb2a717df29912b743a281f97c1,0a4c463a2fa1e7542b61aa48800091ab688eb0a14bebf536638f411f5454c9343b9aa6402b4694f0a89b624407a5f43f0a38fc35216bb18aab7dc41ef9f056b1,10000,SHA512

Le hachage du mot de passe ici peut être généré via une autre image Docker d'InterSystems, par ex. avec la ligne suivante appelée dans un terminal (en savoir plus à propos de passwordhash):

docker run --rm -it containers.intersystems.com/intersystems/passwordhash:1.1 -algorithm SHA512 -workfactor 10000

La commande de fusion (merge) peut être appelée dans Dockerfile like this:

iris merge IRIS merge.cpf && \

D'autres types d'actions de fusion et différents paramètres sont disponibles dans la documentation IRIS.

Exécuter un code d'initialisation arbitraire

Un autre cas d'utilisation populaire consiste à exécuter un code personnalisé arbitraire pour charger des données, des variables d'initialisation et charger du code à partir du référentiel, par exemple, sous forme de package IPM. Habituellement, dans les modèles IRIS, il existe un fichier spécial iris.script qui contient un tel code sous forme d'ObjectScript. J'ai gardé le fichier iris.script dans le référentiel juste pour montrer comment l'utiliser avec ObjectScript.

Dans ce modèle Python, vous pouvez trouver l'exemple d'un tel code d'initialisation dans un fichier iris_script.py. Voyons ce qu'il contient :

import glob

import os

import iris

import pandas as pd

from sqlalchemy import create_engine

from iris import ipm

# switch namespace to the %SYS namespace
iris.system.Process.SetNamespace("%SYS")

# set credentials to not expire
iris.cls('Security.Users').UnExpireUserPasswords("*")

# switch namespace to IRISAPP built by merge.cpf
iris.system.Process.SetNamespace("IRISAPP")

# load ipm package listed in module.xml
#iris.cls('%ZPM.PackageManager').Shell("load /home/irisowner/dev -v")
assert ipm('load /home/irisowner/dev -v')

# load demo data
engine = create_engine('iris+emb:///')

# list all csv files in the demo data folder
for files in glob.glob('/home/irisowner/dev/data/*.csv'):

# get the file name without the extension
table_name = os.path.splitext(os.path.basename(files))[0]

# load the csv file into a pandas dataframe
df = pd.read_csv(files)

# write the dataframe to IRIS
df.to_sql(table_name, engine, if_exists='replace', index=False, schema='dc_demo')

Le code est plutôt explicite et il contient la démonstration de la modification des espaces de noms, du chargement du code du dépôt sous la forme d'un module IPM, de l'importation de fichiers csv contenus dans le dossier /data du dépôt à l'aide de la bibliothèque sqlalchemy.

Que fait le modèle 

Fondamentalement, ce modèle fournit des exemples sur la façon dont Embedded Python peut être utilisé avec IRIS.

1. Appeler Python à partir d'ObjectScrip

Pour en faire la démonstration, nous avons plusieurs classes ObjectScript dans le référentiel.

Pour tester cette approche, ouvrez le terminal IRIS et exécutez :

IRISAPP>d ##class(dc.python.test).Hello()

World

ce test montre comment utiliser les fonctions dans le code sample.py dans IRIS en utilisant Embedded Python.

2. Reportez-vous à IRIS depuis pytho

Pour le tester, vous pouvez exécuter irisapp.py qui effectue différentes opérations avec la base de données IRIS. Pour exécuter toutes les sessions de test de démarrage du terminal dans Docker :

# attach to the running IRIS container

docker-compose exec iris bash

# run the script

$ irispython ./python/irisapp.py

3. Building Python Flask REST API that works with IRIS

Il existe également un exemple d'API REST en python réalisée avec Flask que vous pourriez utiliser dans vos applications et que vous pouvez trouver dans /python/flask/app.py

Pour démarrer l’API Flask REST, procédez :

$ docker-compose exec iris bash

# irispython /python/flask/app.py

Ensuite, vous pouvez tester le serveur sur http://localhost:55030/.

Et voici deux exemples sur la façon d'ajouter un nouvel enregistrement dans IRIS et de lire un enregistrement :

POST http://localhost:55030/persistentclass

Content-Type: application/json

Accept: application/json

{

"test": "toto"

}

Result:

json

{

"id": 1,

"test": "toto"

}


GET http://localhost:55030/persistentclass/1

Accept: application/json

Result:

json

{

"id": 1,

"test": "toto"

}

4. Déploiement

Le déploiement de la solution sur les systèmes IRIS peut être effectué via IPM. Pour cela nous avons un module.xml IPM qui fournira des fichiers ObjectScript et Python à un système IRIS cible à partir d'un registre IPM dans lequel vous publierez le module.

Merci beaucoup à @Guillaume Rongier et @Dmitry Maslennikov qui a beaucoup aidé à créer le modèle et à rendre possible l'approche "Pure Python" .

Il y a aussi des approches plus "radicales" pour organiser de tels modèles - voici les exemples "no dockerfile" et "no objectscript" de @Dmitry Maslennikov, et ici un modèle d'interopérabilité "embedded python" par @Guillaume Rongier.

Discussão (0)1
Entre ou crie uma conta para continuar
Artigo
· Set. 3, 2023 5min de leitura

Initializing InterSystems IRIS Docker Image with Python

While starting the development with IRIS we have a distribution kit or in case of Docker we are pulling the docker image and then often we need to initialize it and setup the development environment. We might need to create databases, namespaces, turn on/off some services, create resources. We often need to import code and data into IRIS instance and run some custom code to init the solution.

And there plenty of templates on Open Exchange where we suggest how to init REST, Interoperability, Analytics, Fullstack and many other templates with ObjectScript. What if we want to use only Python to setup the development environment for Embedded Python project with IRIS?

So, the recent release of Embedded Python template is the pure python boilerplate that could be a starting point for developers that build python projects with no need to use and learn ObjectScript. This article expresses how this template could be used to initialize IRIS. Here we go!

Ok!

Creating Database and Namespace

Often we need to create database and namespace. This could be done with merge cpf functionality of IRIS, and here is the merge file that does the thing:

[Actions]
CreateResource:Name=%DB_IRISAPP_DATA,Description="IRISAPP_DATA database"
CreateDatabase:Name=IRISAPP_DATA,Directory=/usr/irissys/mgr/IRISAPP_DATA,Resource=%DB_IRISAPP_DATA
CreateResource:Name=%DB_IRISAPP_CODE,Description="IRISAPP_CODE database"
CreateDatabase:Name=IRISAPP_CODE,Directory=/usr/irissys/mgr/IRISAPP_CODE,Resource=%DB_IRISAPP_CODE
CreateNamespace:Name=IRISAPP,Globals=IRISAPP_DATA,Routines=IRISAPP_CODE,Interop=1
ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=48
ModifyUser:Name=SuperUser,PasswordHash=a31d24aecc0bfe560a7e45bd913ad27c667dc25a75cbfd358c451bb595b6bd52bd25c82cafaa23ca1dd30b3b4947d12d3bb0ffb2a717df29912b743a281f97c1,0a4c463a2fa1e7542b61aa48800091ab688eb0a14bebf536638f411f5454c9343b9aa6402b4694f0a89b624407a5f43f0a38fc35216bb18aab7dc41ef9f056b1,10000,SHA512

Merge cpf contains Actions which in this case create dabasases IRISAPP_DATA and IRISAPP_CODE for data and code respectively, the related IRISAPP namespace to access it and the related resources %IRISAPP_DATA and %IRISAPP_CODE" to manage the access.

This Merge cpf also enables Callin service to make Embedded python work via ModifyService action:

ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=48

The last action is an example how you can securely set user's password, using ModifyUser action:

ModifyUser:Name=SuperUser,PasswordHash=a31d24aecc0bfe560a7e45bd913ad27c667dc25a75cbfd358c451bb595b6bd52bd25c82cafaa23ca1dd30b3b4947d12d3bb0ffb2a717df29912b743a281f97c1,0a4c463a2fa1e7542b61aa48800091ab688eb0a14bebf536638f411f5454c9343b9aa6402b4694f0a89b624407a5f43f0a38fc35216bb18aab7dc41ef9f056b1,10000,SHA512

The password hash here can be generated via another docker image from InterSystems, e.g. with the following line called in a terminal (learn more about passwordhash):

docker run --rm -it containers.intersystems.com/intersystems/passwordhash:1.1 -algorithm SHA512 -workfactor 10000

merge command is could be called in Dockerfile like this:

iris merge IRIS merge.cpf && \

Other types of merge actions and different settings available for IRIS could be found in documentation.

Running an Arbitrary Init Code

Another popular use case is to run an arbitrary custom code to load data, init variables and load code from the repository e.g. in a form of IPM package. Usually in IRIS templates there is a special file iris.script that contains such a code in form of ObjectScript. I kept the iris.script file in the repository just to demo how it have been used with ObjectScript. 

In this python template you can find the example of such init code in a iris_script.py file. Let's see what's there:

import glob

import os

import iris

import pandas as pd

from sqlalchemy import create_engine

from iris import ipm

# switch namespace to the %SYS namespace
iris.system.Process.SetNamespace("%SYS")

# set credentials to not expire
iris.cls('Security.Users').UnExpireUserPasswords("*")

# switch namespace to IRISAPP built by merge.cpf
iris.system.Process.SetNamespace("IRISAPP")

# load ipm package listed in module.xml
#iris.cls('%ZPM.PackageManager').Shell("load /home/irisowner/dev -v")
assert ipm('load /home/irisowner/dev -v')

# load demo data
engine = create_engine('iris+emb:///')

# list all csv files in the demo data folder
for files in glob.glob('/home/irisowner/dev/data/*.csv'):

# get the file name without the extension
table_name = os.path.splitext(os.path.basename(files))[0]

# load the csv file into a pandas dataframe
df = pd.read_csv(files)

# write the dataframe to IRIS
df.to_sql(table_name, engine, if_exists='replace', index=False, schema='dc_demo')

The code is rather self-explanatory and it has the demo of changing namespaces, loading repo code in form of IPM module, importing csv files that contained in /data folder of the repo using sqlalchemy lib.

What Does the Template do?

Basically this template provides examples how can  Embedded Python by used with IRIS. 

1. Calling Python From ObjectScript

To demo it we have several ObjectScript classes in the repo.

To test the approach open IRIS terminal and run:

IRISAPP>d ##class(dc.python.test).Hello()

World

this test demoes how you can use functions in sample.py code in IRIS using Embedded Python.

2. Refer to IRIS from python

To test this you can run irisapp.py that performs different operations with IRIS database. To run all the test start terminal session in docker:

# attach to the running IRIS container

docker-compose exec iris bash

# run the script

$ irispython ./python/irisapp.py

3. Building Python Flask REST API that works with IRIS

There is also an example of REST api in python made with Flask that you could use in your applications that you can find in /python/flask/app.py

To start Flask REST api do:

$ docker-compose exec iris bash

# irispython /python/flask/app.py

Then you can test the server at http://localhost:55030/.

And here are two examples on how to add a new record in IRIS and read a record:

POST http://localhost:55030/persistentclass

Content-Type: application/json

Accept: application/json

{

"test": "toto"

}

Result:

json

{

"id": 1,

"test": "toto"

}


GET http://localhost:55030/persistentclass/1

Accept: application/json

Result:

json

{

"id": 1,

"test": "toto"

}

4. Deployment

The deployment of the solution to IRIS systems can be performed via IPM. For that purpose we have an IPM module.xml that will deliver ObjectScript and Python files to a target IRIS system from an IPM Registry you will publish module at.

Thanks a lot to @Guillaume Rongier and @Dmitry Maslennikov who helped a lot to create the template and make "Pure Python" approach possible.

There are more "radical" approaches in organizing such templates - here is the "no dockerfile" and "no objedctscript" sample by @Dmitry Maslennikov ,

here is "embedded python" template by @Guillaume Rongier.

1 Comment
Discussão (1)2
Entre ou crie uma conta para continuar
Pergunta
· Ago. 31, 2023

How to Search If OBX 5 contains a certain value in consecutive OBXs in BPL

I need to search for the following values "SEDATION:  " and "Procedure" In consecutive OBX 5 as seen below. Note that sometimes the OBX 5 containing "Procedure" may be followed by other characters/text hence I am leaning towards using a contains statement. 

OBX|028|TX|OP^Operative Note^D4D^11504-8^Surgical operation note^XXX||SEDATION:  ||||||C|
OBX|029|TX|OP^Operative Note^D4D^11504-8^Surgical operation note^XXX||Procedure:

Only when they appear consecutively do I want to process the message as an ORU using the BPL. Not sure how to go about it and would appreciate any assistance. Thanks 

8 Comments
Discussão (8)2
Entre ou crie uma conta para continuar
Pergunta
· Ago. 31, 2023

How exactly does the OperationLimit Property on the Regex-Matcher work, and how do I get it to work?

Hi there,

I want to use regex in my code, and I saw that the %Regex.Matcher class contains a property "OperationLimit" that you can also set to a number of steps that the regex engine should take maximum in analysing a given string. So far so good.

I tried to set the property with the function OperationLimitSet() to a silly value like 3. In 3 steps only very few regex should be executed, right? But what I found is that my regex always comes up with a solution. Here is what I did:

 

First I initialised my %Regex.Matcher.

set m = ##class(%Regex.Matcher).%New("(.+)\@(.+)\.(.+)")
do m.OperationLimitSet(3)
do m.TextSet("thisismytest@email.com")

 

Then I ran the regex and found my 3 groups.

zw m.Locate()
1
zw m.Group(1)
"thisismytest"
zw m.Group(2)
"email"
zw m.Group(3)
"com"

 

Now maybe I have completely misunderstood the OperationLimit property, or my implementation of this simple regex matcher is faulty, but the documentation clearly states: "Setting OperationLimit to a positive integer will cause a match operation to signal a TimeOut error after the specified number of clusters of steps by the match engine".  As I am using the Locate() function and not the Match() function, I wondered if the documentation specifically talks about the Match() function. But both the Locate() and Match() function execute without any problem.

set m = ##class(%Regex.Matcher).%New("(.+)\@(.+)\.(.+)")
do m.OperationLimitSet(3)
do m.TextSet("thisismytest@email.com")

zw m.Match()
1

I would appreciate any input as to why my regex is still running perfectly and what I can do to prevent this, as I would obviously like to set a realistic OperationLimit of 4000 or something in that range in the future.

Thanks for your help!

1 Comment
Discussão (1)2
Entre ou crie uma conta para continuar