Skip to main content
Solved

PythonCaller read list error

  • November 22, 2024
  • 2 replies
  • 66 views

asablomberg
Contributor
Forum|alt.badge.img+8

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}'")

 

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.

2 replies

david_r
Celebrity
  • 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+8
  • 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)