[BUG] Json encode function break the runNamedQuery

Hello there,

TLDR : I use the perspective JSON encode function to convert Object from custom data to JSON and it makes it impossible for the RunNamedQuery function to find the query.

I tried another way to pass my params to my script because its getting annoying to go get each binding in the script.
So I just binded a custom object in my script and used JsonEncode to be able to use it.

params = system.util.jsonEncode(self.parent.custom.ResultControle)
query = "Qualite/INSERT_ControleQualite"
	
system.db.runNamedQuery(query,params)
	

When I run my script (on a button event 'onActionPerformed') I get the folowing error.

com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
  File "<function:runAction>", line 7, in runAction
com.inductiveautomation.ignition.common.project.ProjectNotFoundException: com.inductiveautomation.ignition.common.project.ProjectNotFoundException: project not found: Qualite/INSERT_ControleQualite

	caused by org.python.core.PyException
Traceback (most recent call last):
  File "<function:runAction>", line 7, in runAction
com.inductiveautomation.ignition.common.project.ProjectNotFoundException: com.inductiveautomation.ignition.common.project.ProjectNotFoundException: project not found: Qualite/INSERT_ControleQualite

	caused by ProjectNotFoundException: project not found: Qualite/INSERT_ControleQualite

Ignition v8.1.39 (b2024040909)
Java: Azul Systems, Inc. 17.0.10

Have one of you already seen this kind of error ?

I tried with a direct binding of each params on my script and it works fine.

	#Data = system.util.jsonEncode(self.parent.custom.ResultControle)
	query = "Qualite/INSERT_ControleQualite"
	params = { "ID_Controle": self.parent.custom.ResultControle.ID_Controle,
		  "ID_ORDO": self.parent.custom.ResultControle.ID_ORDO,
		  "ControleHaut": self.parent.custom.ResultControle.ControleHaut,
		  "ControleMilieu": self.parent.custom.ResultControle.ControleMilieu,
		  "ControleBas": self.parent.custom.ResultControle.ControleBas,
		  "Equipe": self.parent.custom.ResultControle.Equipe,
		  "Pilote": self.parent.custom.ResultControle.Pilote,
		  "Date":self.parent.custom.ResultControle.Date
		}
	system.db.runNamedQuery(query,params)

Thanks for your help.

Json encode turns an object into a string (formated to be readable by json parse), that is not what the runNamedQuery expects.
Because you are giving 2 string parameters, it things the first one is a project, instead of the query name.
It looks like you should be able to just do this (though i cant tell for sure without seeing the prop)
params = self.parent.custom.ResultControle

3 Likes

Hmm,
I tried again but I don't know why I have this message:

Error running action 'component.onActionPerformed' on Views_Operator/View_Qualite/View_ControleQualite@D/root/Colorimetrie/Enregistrer: Traceback (most recent call last): File "<function:runAction>", line 5, in runAction at com.inductiveautomation.ignition.common.TypeUtilities.coerce(TypeUtilities.java:1681) at com.inductiveautomation.ignition.common.script.builtin.PyArgumentMap.coerce(PyArgumentMap.java:130) at com.inductiveautomation.ignition.common.script.builtin.PyArgumentMap.interpretPyArgs(PyArgumentMap.java:82) at com.inductiveautomation.ignition.common.script.builtin.PyArgumentMap.interpretPyArgs(PyArgumentMap.java:40) at com.inductiveautomation.ignition.gateway.script.GatewayDBUtilities.interpretWithOptionalProject(GatewayDBUtilities.java:487) at com.inductiveautomation.ignition.gateway.script.GatewayDBUtilities.runNamedQuery(GatewayDBUtilities.java:392) at jdk.internal.reflect.GeneratedMethodAccessor119.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) java.lang.ClassCastException: java.lang.ClassCastException: Cannot coerce value '<ObjectWrapper>: {u'ID_Controle': 0L, u'ID_ORDO': 56L, u'Pilote': u'', u'ControleMilieu': 0L, u'Equipe': 0, u'ControleBas': 0L, u'Date': Wed Jun 12 08:16:35 CEST 2024, u'ControleHaut': 0L}' into type: interface java.util.Map

huh try

params = dict(self.parent.custom.ResultControle)

seems like if you have a nested dict you might also have to do this instead

1 Like

I tested this, and using the dict constructor appears to do the job even with nested objects.

I also tried the TypeUtilities.pyToJava() function but that seems to just return the ObjectWrapper, which makes since, beings as it is technically a Java Object.

Curiously, the TypeUtilities helper functions are missing a toMap() function.

You could probably also accomplish this by encoding it as a JSON string, then using the TypeUtilities.gsonToPy() function, but that seems a bit round about if dict() works.

1 Like

you could encode and decode json, but not sure if things like dates will work like that

1 Like