Created on 11-05-2018 08:43 PM - edited 08-17-2019 06:24 PM
I want to check if a product ID exists in a file. I came up with following python script:
#!/usr/bin/python import os import java.io flowFile = session.get() exists = False if (flowFile != None): if !os.path.exists('/home/nifi/products.csv'): session.transfer(flowFile, REL_SUCCESS) else: asin = flowFile.getAttribute('asin') with open('/home/nifi/products.csv') as csv: if asin in csv.read(): exists = True session.transfer(flowFile, REL_FAILURE) if !exists: session.transfer(flowFile, REL_SUCCESS)
However I am getting an error which I find really hard to interpret. It basically just says javax.script.ScriptException: NameError: name 's' is not defined in <script> at line number 9 Any ideas whats causing this?
2018-11-05 19:27:29,267 ERROR [Timer-Driven Process Thread-2] o.a.nifi.processors.script.ExecuteScript ExecuteScript[id=e52f46d5-0166-1000-fc42-8e9565527c21] Failed to process session due to org.apache.nifi.processor.exception.ProcessException: javax.script.ScriptException: NameError: name 's' is not defined in <script> at line number 9: org.apache.nifi.processor.exception.ProcessException: javax.script.ScriptException: NameError: name 's' is not defined in <script> at line number 9 org.apache.nifi.processor.exception.ProcessException: javax.script.ScriptException: NameError: name 's' is not defined in <script> at line number 9 at org.apache.nifi.processors.script.ExecuteScript.onTrigger(ExecuteScript.java:239) at org.apache.nifi.controller.StandardProcessorNode.onTrigger(StandardProcessorNode.java:1165) at org.apache.nifi.controller.tasks.ConnectableTask.invoke(ConnectableTask.java:203) at org.apache.nifi.controller.scheduling.TimerDrivenSchedulingAgent$1.run(TimerDrivenSchedulingAgent.java:117) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: javax.script.ScriptException: NameError: name 's' is not defined in <script> at line number 9 at org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:222) at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:59) at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31) at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) at org.apache.nifi.script.impl.JythonScriptEngineConfigurator.eval(JythonScriptEngineConfigurator.java:59) at org.apache.nifi.processors.script.ExecuteScript.onTrigger(ExecuteScript.java:229) ... 10 common frames omitted Caused by: org.python.core.PyException: null at org.python.core.Py.NameError(Py.java:290) at org.python.core.PyFrame.getname(PyFrame.java:257) at org.python.pycode._pyx189507.f$0(<script>:18) at org.python.pycode._pyx189507.call_function(<script>) at org.python.core.PyTableCode.call(PyTableCode.java:171) at org.python.core.PyCode.call(PyCode.java:18) at org.python.core.Py.runCode(Py.java:1614) at org.python.core.__builtin__.eval(__builtin__.java:497) at org.python.core.__builtin__.eval(__builtin__.java:501) at org.python.util.PythonInterpreter.eval(PythonInterpreter.java:259) at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:57) ... 14 common frames omitted
Created 11-05-2018 09:36 PM
That error message is misleading, Jython doesn't put the "real" error message in the getMessage() method of its exception(s), see this issue. You've got a couple things going on here, the first is that you can't use the bang character (!) for a boolean NOT, instead you should use "not". After that, if the file doesn't exist, it will be transferred to REL_SUCCESS in your first "if" statement, and then since "exists" is never set to True, then it will try to transfer the same flow file again. Even though they're the same relationship, the framework notes that a flow file has already been marked for transfer, and will complain if it is transferred again (even to the same relationship), as this identifies a logic bug.
I'm not exactly following what you're trying to do here, please feel free to elaborate and I can help out getting you where you need to go.
Created 11-06-2018 07:23 AM
So along the flow I have an attribute, which is called asin (aka product ID). The flow should fail when an ID already exists in a local csv file. With your help I changed my code to
#!/usr/bin/python import os import java.io flowFile = session.get() productFound = False if (flowFile != None): if os.path.exists('/home/nifi/products.csv'): asin = flowFile.getAttribute('asin') with open('/home/nifi/products.csv') as csv: if asin in csv.read(): productFound = True if productFound: session.transfer(flowFile, REL_FAILURE) else: session.transfer(flowFile, REL_SUCCESS)
I falsely assumed that I could call REL_FAILURE/SUCCESS multiple times.