Skip to main content
Solved

PythonCaller read list error

  • November 22, 2024
  • 2 replies
  • 35 views

asablomberg
Contributor
Forum|alt.badge.img+7

I want to loop through the list ‘attribute’ in a PythonCaller and change some values, but I get an error. Line 34 is the for-loop.

 

  File "<string>", line 34, in input
Python Exception <TypeError>: 'NoneType' object is not iterable

 

Can you see the error?

 

    def input(self, feature: fmeobjects.FMEFeature):

        feat = feature.getAttribute("attribute{}.attribute")

        for obj in feat:
            if "fme_varchar" in obj.fme_data_type:

 

 

Best answer by david_r

Unfortunately you cannot read an FME list like that, you have to reference every child attribute.

Try something like:

names = feature.getAttribute("attribute{}.name")
data_types = feature.getAttribute("attribute{}.fme_data_type")
attributes = zip(names, data_types)

for (name, data_type) in attributes:
    if "fme_varchar" in data_type:
        # Do something
        print(f"Attribute '{name}' is of type '{data_type}'")

 

View original
Did this help you find an answer to your question?

2 replies

david_r
Evangelist
  • Best Answer
  • November 22, 2024

Unfortunately you cannot read an FME list like that, you have to reference every child attribute.

Try something like:

names = feature.getAttribute("attribute{}.name")
data_types = feature.getAttribute("attribute{}.fme_data_type")
attributes = zip(names, data_types)

for (name, data_type) in attributes:
    if "fme_varchar" in data_type:
        # Do something
        print(f"Attribute '{name}' is of type '{data_type}'")

 


asablomberg
Contributor
Forum|alt.badge.img+7
  • Author
  • Contributor
  • November 25, 2024

Thank you! Here is my result. Any more input and comments are welcome. :) Is there maybe a better alternative than using the loop counter ‘i’?

 

    def input(self, feature: fmeobjects.FMEFeature):
        names = feature.getAttribute("attribute{}.name")
        data_types = feature.getAttribute("attribute{}.fme_data_type")
        attributes = zip(names, data_types)
        delimiter = ""

        i = 0
        for (name, data_type) in attributes:

            if "fme_varchar" in data_type:
                #extract only numbers from datatype
                temp = re.findall(r'\d+', data_type)
                res = int(delimiter.join(temp))

                # if column name longer than name, alter datatype
                if len(name) > res:
                    res = len(name)
                    new_data_type = "fme_varchar(" + str(res) + ")"
                    feature.setAttribute("attribute{%d}.fme_data_type" % i, new_data_type)

            i = i + 1

        self.pyoutput(feature)

 


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings