accéder à la publication Guillaume Rongier · Avr 23 Bonjour, Je pense que vous n'avez pas accès, cette commande comme la majorité des commandes objectscripts sont codées en C. Et ce code C n'est pas public.
accéder à la publication Guillaume Rongier · Fév 26 Ok, effectivement, les choses semblent avoir changées. D'apres la doc kong : https://docs.konghq.com/gateway/latest/kong-manager/auth/super-admin/#cr... Lors de la migration de kong, tu dois passer le paramètre : KONG_PASSWORD Activer le RBAC : KONG_ENFORCE_RBAC: 'on' Et te connecter avec : Login : kong_admin et Mot de passe : Celui spécifié dans la migration Après tu dois avoir accès au bouton Invite Admin
accéder à la publication Guillaume Rongier · Fév 6 autre solution est de forcer l'autoCommit lors de la création de l'engine avec embeddded python : engine = create_engine('iris+emb:///', connect_args={'autoCommit': True})
accéder à la publication Guillaume Rongier · Fév 6 effectivement, il y a un problem de lock avec SQLAlchmy et embedded python. ce que tu proposes, c'est de passer d'une connexion SQLAlchmy avec EmbeddedPython vers une connexion classique sur TCP/IP. Pourquoi cela ne fonctionnerait pas en production ? Tu as à variabiliser les login et mot de passe et le tour est joué. L'adresse du server ne doit pas changer, ca sera toujours localhost dans ton cas.
accéder à la publication Guillaume Rongier · Déc 22, 2023 Bonjour, La facon, la plus simple aujourd'hui est de passer par du code Python ou Java pour ce genre d'opération : Java : https://openexchange.intersystems.com/package/excel-java-iris Python : https://openexchange.intersystems.com/package/eap-sql2xlsx https://openexchange.intersystems.com/package/appmsw-sql2xlsx Ou encore utiliser le super module d'interopérabilité 100% python : iop : https://openexchange.intersystems.com/package/interoperability-embedded-... https://github.com/grongierisc/formation-template-python
accéder à la publication Guillaume Rongier · Déc 21, 2023 Bonjour, C'est la connexion sqlalchemy qui creer une transaction qui n'est jamais relâchée, le code suivant devrait fonctionner: ClassMethod creerFichierCSV( query As %String, filename As %String) [ Language = python ] { import pandas as pd from sqlalchemy import create_engine,text engine = create_engine('iris+emb:///') try: df = pd.read_sql(text("SELECT * from Ens_Util.Log"),engine) except Exception as e: raise e finally: engine.dispose() df.to_csv("toto", index=False, header = True, encoding='utf-8', sep =';') return } Pour relâcher la transaction, aller dans : Puis selection la transaction : et enfin, la terminer :
accéder à la publication Guillaume Rongier · Déc 21, 2023 Je ne sais pas si VsCode support cette fonctionnalité, ce pendant, il est tout à fait possible d'ouvrir un ticket pour en faire une demande : https://github.com/intersystems-community/vscode-objectscript/issues J'imagine que ces propriétés sont liées aux objects projects qui aident aux déploiements. Pour accéder aux options de projets il faut monter un dossier isfs qui fait la passerelle entre iris et vscode : https://docs.intersystems.com/components/csp/docbook/DocBook.UI.Page.cls...
accéder à la publication Guillaume Rongier · Déc 18, 2023 Bonjour, Je rencontre aussi ce problème, c'est lié à la version 2023.1 d'iris et pas à VsCode. La redirection des erreurs dans la sortie standard ne se fait pas systématiquement. C'est résolu à partir de la 2023.3. Un workaround : Do $system.OBJ.SetQualifiers("/multicompile=0",1) Cette commande désactive la compilation parallèle dans tout le système. Cela ne pose pas de problème si des classes individuelles sont compilées. Par contre, elle est plus lente pour de nombreuses classes. Mais vous pouvez le réactiver en utilisant le CompileFlag /multicompile=1 si vous devez compiler beaucoup de classes à la fois : do $SYSTEM.OBJ.Compile("Demo.Demo","/multicompile=1",.err)
accéder à la publication Guillaume Rongier · Déc 13, 2023 Salut, As tu essayé d'ajouter la commande over + un ordre dans ton ROW_NUMBER() ? C'est recommandé car sinon le résultat peut être aléatoire. SELECT * FROM (SELECT _DATA.ID, ROW_NUMBER() over (order by _DATA.ID) _RN, COUNT(*) _COUNT FROM XX.srsshiptype _DATA ) WHERE _RN BETWEEN 1 and 1000
accéder à la publication Guillaume Rongier · Déc 12, 2023 Salut, As tu activé le service %Service_Callin ? Par default il est désactivé mais obligatoire pour embedded python.
accéder à la publication Guillaume Rongier · Déc 11, 2023 C'est bizarre, si l'inspect fonctionne, le runserver doit aussi fonctionner. Tu peux visualiser les log d'audit pour avoir plus de détail sur l'erreur de connexion : Dans cet exemple, j'ai essayé de me connecter avec un user grongier en lieu et place de SuperUser, la faute à : "USER": os.environ.get("USER", "SuperUser"), dans mon settings.py
accéder à la publication Guillaume Rongier · Déc 11, 2023 C'est le principe des streams d'écrire chunk par chunk.
accéder à la publication Guillaume Rongier · Déc 11, 2023 Salut Cyril, La méthode PutStream() prend un objet %Stream d'IRIS en paramètre. Il faut donc que tu convertisses ton fichier en %Stream avant de l'envoyer. Exemple : XMessage from grongier.pex import Message from dataclasses import dataclass @dataclass class XMessage(Message): StringStream: str BinaryStream: bytes BusinessOperation from grongier.pex import BusinessOperation from datetime import datetime from X.xImport import XMessage import iris class XArticleExport(BusinessOperation): def get_adapter_type(): return "EnsLib.FTP.OutboundAdapter" def on_init(self): return super().on_init() def on_message(self, request: XMessage): if hasattr(request, "Stream"): # Préparation du stream stream = iris.cls("%Stream.GlobalCharacter")._New() source = "" # Si le stream est en string on l'utilise tel quel if request.StringStream: source = request.StringStream elif request.BinaryStream: source = request.BinaryStream.decode("utf-8") # On écrit le contenu du fichier dans le stream n = 4092 chunks = [source[i:i+n] for i in range(0, len(source), n)] for chunk in chunks: stream.Write(chunk) filename = "exportArticles_" + datetime.now().strftime("%Y%m%d") + ".csv" esc: int = self.Adapter.PutStream(filename, stream) if esc == 1: self.log_info("File imported successfully with code : " + esc) else: self.log_error("Pas de stream reçu ! Code: " + esc) return super().on_message(request)
accéder à la publication Guillaume Rongier · Déc 4, 2023 Salut, Peux-tu essayer cette commande : python -m grongier.pex._cli Je vais regarder en parallèle, le problème avec windows (pas facile, j'ai pas de VM windows à disposition :()
accéder à la publication Guillaume Rongier · Nov 28, 2023 Si tu peux changer de namespace quand tu le souhaites pour ca deux facons : avant d'executer iop tu changes la variable d'environnement IRISNAMESPACE. export IRISNAMESPACE=TEST iop -m path/to/my_settings.py dans ton fichier my_settings.py tu peux changer le namespace avec la fonction suivante : import iris # switch namespace to the TEST namespace iris.system.Process.SetNamespace("TEST") # print the current namespace print(iris.system.Process.NameSpace()) from TEST.bo import MyBo CLASSES = { "MyIRIS.MyBo": MyBo } PRODUCTIONS = [ { "MyIRIS.Production": { "@TestingEnable": "true", "@Name": "MyIRIS.Production", "Item": [ { "@Name": "Instance.Of.MyBo", "@ClassName": "MyIRIS.MyBo", } ] } } ]
accéder à la publication Guillaume Rongier · Nov 28, 2023 humm, ne pas confondre la PWG (Private WebGateway) et la WebGateway. La private webgateway est un mini apache qui est embarqué dans iris. Il n'a pas a etre configuré. De plus, dans la configue pour acceder à ce portail il ne faut pas oublier d'ajouter ton ip en white list System_Manager=*.*.*.* Pourquoi souhaites-tu le configurer ?
accéder à la publication Guillaume Rongier · Nov 28, 2023 Salut, il manque un d à @TestingEnable @TestingEnable != @TestingEnabled
accéder à la publication Guillaume Rongier · Nov 21, 2023 Super : Pour information, les métrics interop ne sont pas activés par default. Pour les activer : do ##class(Ens.Util.Statistics).EnableSAMForNamespace() Plus d'information ici sur la doc
accéder à la publication Guillaume Rongier · Nov 16, 2023 Bonjour, Effectivement, le service EnsLib.SQL.Service.GenericService est un service de type "Business Service" qui va générer un message pour chaque ligne de résultat de la requête SQL. Ce service est donc adapté pour des requêtes qui retournent un nombre limité de lignes. Je pense que tu vas devoir passer par du code custom. Voici un exemple en Python qui est relativement simple à mettre en oeuvre. Le bs : from grongier.pex import BusinessService import pandas as pd from sqlalchemy import create_engine from .msg import SQLMessage class SQLService(BusinessService): def __init__(self, **kwargs): self.sql = None self.conn = None self.target = None def on_init(self): if not hasattr(self, 'sql'): raise Exception('Missing sql attribute') if not hasattr(self, 'conn'): raise Exception('Missing conn attribute') if not hasattr(self, 'target'): raise Exception('Missing target attribute') self.engine = create_engine(self.conn) # raise an error if cannot connect to the database self.engine.connect() def get_adapter_type(): """ Name of the registred Adapter """ return "Ens.InboundAdapter" def on_process_input(self, message_input): # create a dataframe from the sql query df = pd.read_sql(self.sql, self.engine) # create a message message = SQLMessage(dataframe=df) # send the message to the target self.send_request_sync(self.target, message) return Ici on utilise la force de pandas pour créer un dataframe à partir du résultat de la requête SQL. On crée ensuite un message qui contient le dataframe et on l'envoie au target. La configuration est faite à partir de propriétés suivantes : sql : la requête SQL conn : la connexion à la base de données target : le target Le message : from grongier.pex import Message from dataclasses import dataclass from pandas.core.frame import DataFrame @dataclass class SQLMessage(Message): dataframe: DataFrame = None Le message qui contient le dataframe. La target qui permet de créer le fichier csv : from grongier.pex import BusinessOperation from .msg import SQLMessage import pandas as pd class CSVOperation(BusinessOperation): def __init__(self, **kwargs): self.filename = None def on_init(self): if not hasattr(self, 'filename'): raise Exception('Missing filename attribute') def on_sql_message(self, message_input: SQLMessage): # get the dataframe from the message df = message_input.dataframe # create a csv file df.to_csv(self.filename, index=False) return La configuration est faite à partir du fichier settings.py : from sqltocsv import bo,bs import os CLASSES = { 'Python.Bs.SQLService': bs.SQLService, 'Python.Bo.CSVOperation': bo.CSVOperation } db_user = os.environ.get('POSTGRES_USER', 'DemoData') db_password = os.environ.get('POSTGRES_PASSWORD', 'DemoData') db_host = os.environ.get('POSTGRES_HOST', 'db') db_port = os.environ.get('POSTGRES_PORT', '5432') db_name = os.environ.get('POSTGRES_DB', 'DemoData') PRODUCTIONS = [{ "Python.Production": { "@Name": "Python.Production", "@LogGeneralTraceEvents": "false", "Description": "", "ActorPoolSize": "2", "Item": [ { "@Name": "Python.Bs.SQLService", "@Category": "", "@ClassName": "Python.Bs.SQLService", "@PoolSize": "1", "@Enabled": "true", "@Foreground": "false", "@Comment": "", "@LogTraceEvents": "false", "@Schedule": "", "Setting": { "@Target": "Host", "@Name": "%settings", "#text": "sql=select * from formation\nconn=postgresql://"+db_user+":"+db_password+"@"+db_host+":"+db_port+"/"+db_name+"\ntarget=Python.Bo.CSVOperation" } }, { "@Name": "Python.Bo.CSVOperation", "@Category": "", "@ClassName": "Python.Bo.CSVOperation", "@PoolSize": "1", "@Enabled": "true", "@Foreground": "false", "@Comment": "", "@LogTraceEvents": "false", "@Schedule": "", "Setting": { "@Target": "Host", "@Name": "%settings", "#text": "filename=/tmp/export.csv" } } ] } }] On utilise les variables d'environnement pour la connexion à la base de données. Tu as l'exemple complet ici : https://github.com/grongierisc/formation-template-python/tree/demo_sqltodb Je laisse un autre membre de la communauté répondre avec une solution en ObjectScript.
accéder à la publication Guillaume Rongier · Nov 7, 2023 Bonjour @Moussa SAMB Je viens de creer un projet example qui permet de se connecter à un server mail type imap en oauth2 : https://github.com/grongierisc/iris-imap-python-adaptor Si ca t'intéresse, je peux te le présenter en détail et l'améliorer pour qu'il corresponde à tes besoins.