Skip to main content
Solved

Bug PythonCaller - Change between FME 2016 and 2017

  • October 2, 2019
  • 4 replies
  • 21 views

arxit
Contributor
Forum|alt.badge.img+5
  • Contributor
  • 34 replies

Hello,

I need to migrate an FME script with PythonCaller, from FME 2016.1.3.2 to FME 2017.1.1.2, but there are differences.

The PythonCaller write to a TXT file, but the problem is not when it is writing : i tried with a print "test" : it works fine with FME 2016 and it doesn't work with FME 2016.

367 features passed into the PythonCaller :

0684Q00000ArErZQAV.png

 

The features with the problem are with fme_feature_type "schema" :

0684Q00000ArEqSQAV.png

 

Is there a difference between 2016 and 2017 in PythonCallers ?

 

The Python Interpreter is the same (2.7).

 

Here is the Python Script (I simplified the script with only elements causing problems)

 

 : 

 

# -*- coding:utf-8 -*-
import fme
import fmeobjects
import os
import unicodedata
from datetime import date
from datetime import datetime

# Template Function interface:
def processFeature(feature):
    pass

# Template Class Interface:
class FeatureProcessor(object):
    def __init__(self):
        
        self.countfeatures = 0
        self.err_structure = ""
        
        
    def input(self,feature):
        self.countfeatures += 1        
        self.pyoutput(feature)

        if feature.getAttribute('_count_structure') >= '1' :
            if feature.getAttribute('_count_structure') == '1' :
                print "TEST"

    def close(self):
        
        
        pass


 

 

Thanks.

Best answer by david_r

Is there a particular reason for doing

self.pyoutput(feature)

before at the very end of the method? 

But the real issue is that newer versions of FME are trying to be more intelligent in differentiating between strings and numeric attributes, and the script makes some assumptions about the attribute data type that are no longer valid. By making the script not assuming the datatype it will work, e.g.

        if str(feature.getAttribute('_count_structure')) >= '1' :
            if str(feature.getAttribute('_count_structure')) == '1' :
                print "TEST"

Or, even better by comparing numerical values rather than strings:

        if int(feature.getAttribute('_count_structure')) >= 1 :
            if int(feature.getAttribute('_count_structure')) == 1 :
                print "TEST"
This post is closed to further activity.
It may be an old question, an answered question, an implemented idea, or a notification-only post.
Please check post dates before relying on any information in a question or answer.
For follow-up or related questions, please post a new question or idea.
If there is a genuine update to be made, please contact us and request that the post is reopened.

4 replies

arxit
Contributor
Forum|alt.badge.img+5
  • Author
  • Contributor
  • 34 replies
  • October 2, 2019

To explain easily the problem, i reproduced it in the attached FMW : it works with FME 2016 and does not with FME 2017

test_script.fmw


david_r
Celebrity
  • 8394 replies
  • Best Answer
  • October 2, 2019

Is there a particular reason for doing

self.pyoutput(feature)

before at the very end of the method? 

But the real issue is that newer versions of FME are trying to be more intelligent in differentiating between strings and numeric attributes, and the script makes some assumptions about the attribute data type that are no longer valid. By making the script not assuming the datatype it will work, e.g.

        if str(feature.getAttribute('_count_structure')) >= '1' :
            if str(feature.getAttribute('_count_structure')) == '1' :
                print "TEST"

Or, even better by comparing numerical values rather than strings:

        if int(feature.getAttribute('_count_structure')) >= 1 :
            if int(feature.getAttribute('_count_structure')) == 1 :
                print "TEST"

jovitaatsafe
Safer
Forum|alt.badge.img+11
  • Safer
  • 635 replies
  • October 2, 2019

Is there a particular reason for doing

self.pyoutput(feature)

before at the very end of the method? 

But the real issue is that newer versions of FME are trying to be more intelligent in differentiating between strings and numeric attributes, and the script makes some assumptions about the attribute data type that are no longer valid. By making the script not assuming the datatype it will work, e.g.

        if str(feature.getAttribute('_count_structure')) >= '1' :
            if str(feature.getAttribute('_count_structure')) == '1' :
                print "TEST"

Or, even better by comparing numerical values rather than strings:

        if int(feature.getAttribute('_count_structure')) >= 1 :
            if int(feature.getAttribute('_count_structure')) == 1 :
                print "TEST"

Hi @arxit,

Just wanted to chime in in agreement with @david_r and to confirm that this is expected behavior and not an issue with the PythonCaller.

Adding onto their answer for anyone else less Python-minded and interested (like me), it looks like in FME 2016 the counter's attribute is created as a string, and so with the quotes around the 1 signifying the comparison as a string, it compares strings to strings, and it prints the TEST.

In 2017, we're handling those attributes better as an integer coming from the Counter, so the quotes around  1 are no longer comparing the right data type (integer to string) and thus needs david_r's changes in the script. 


arxit
Contributor
Forum|alt.badge.img+5
  • Author
  • Contributor
  • 34 replies
  • October 3, 2019

Is there a particular reason for doing

self.pyoutput(feature)

before at the very end of the method? 

But the real issue is that newer versions of FME are trying to be more intelligent in differentiating between strings and numeric attributes, and the script makes some assumptions about the attribute data type that are no longer valid. By making the script not assuming the datatype it will work, e.g.

        if str(feature.getAttribute('_count_structure')) >= '1' :
            if str(feature.getAttribute('_count_structure')) == '1' :
                print "TEST"

Or, even better by comparing numerical values rather than strings:

        if int(feature.getAttribute('_count_structure')) >= 1 :
            if int(feature.getAttribute('_count_structure')) == 1 :
                print "TEST"

Thank you for those explanations.

It works ! But I had to add another Test, to let not the other "None" elements pass :

if feature.getAttribute('_count_structure') is not None :

 

The

self.pyoutput(feature)

is used to create new feature, in the entire FME script (but it is not used in the example FMW I sent)