Skip to main content
Solved

Transfer python dictionnary between 2 Transformers


Forum|alt.badge.img

In a PythonCreator, I create a dictionnary. I'd like to use it in the following Transformer, a PythonCaller as an attribute.

So In the Creator, I finish with "return myDict". In the Caller, I call the attribute myDict.

But when I run the project, in the log, it tells me that :

TypeError: 'NoneType' object is not iterable

Do you have any suggestions?

Thanks

Best answer by david_r

Try this instead:

import json
import fmeobjects

class FeatureCreator(object):

    def __init__(self):
        pass

    def close(self):
        feature = fmeobjects.FMEFeature()
        myDict = {'Commune' : 'Tokyo'}
        feature.setAttribute('my_json', json.dumps(myDict))
        self.pyoutput(feature)

Notice how self.pyoutput(feature) always comes last.

Also notice that you have to import the json module.

If you attach a Logger after this PythonCreator you should get:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Logger_LOGGED'
Attribute(string): `fme_feature_type' has value `PythonCreator'
Attribute(string): `my_json' has value `{"Commune""Tokyo"}'
Geometry Type: Unknown (0)
===========================================================================

Hope this helps.

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

16 replies

david_r
Celebrity
  • June 29, 2016

You can either define your dictionary as a global variable:

global my_dict
my_dict = {1'a'2'b'3'c'}

Then in a different Python transformer you can access it like this:

global my_dict
my_value = my_dict[1]

Alternatively you can pass the dictionary as JSON strings from one transformer to another using the feature attributes.

To convert a dictionary "my_dict" to JSON and store it in the attribute "my_json":

feature.setAttribute('my_json', json.dumps(my_dict))

Then later on you can read the attribute "my_json" and convert it back to a dictionary:

my_dict = json.loads(feature.getAttribute('my_json))

Forum|alt.badge.img
  • Author
  • June 29, 2016

Thanks. But, I have a error in my log saying that the dictionnary isn't a string.

I checked printing the type of it. In the Creator, it is a string. But in the Caller, it became a NonType.

global myDict

 

class FeatureCreator(object):

 

def __init__(self):

 

pass

 

def close(self):

 

feature = fmeobjects.FMEFeature()

 

self.pyoutput(feature)

 

myDict = {'Commune' : 'Tokyo'}

 

feature.setAttribute('my_json', json.dumps(myDict))

 

print json.dumps(myDict)

 

print type(json.dumps(myDict))

Is that because I'm doing it in a method in a class?


Forum|alt.badge.img
  • Author
  • June 29, 2016
david_r wrote:

You can either define your dictionary as a global variable:

global my_dict
my_dict = {1'a'2'b'3'c'}

Then in a different Python transformer you can access it like this:

global my_dict
my_value = my_dict[1]

Alternatively you can pass the dictionary as JSON strings from one transformer to another using the feature attributes.

To convert a dictionary "my_dict" to JSON and store it in the attribute "my_json":

feature.setAttribute('my_json', json.dumps(my_dict))

Then later on you can read the attribute "my_json" and convert it back to a dictionary:

my_dict = json.loads(feature.getAttribute('my_json))

By the way, I'm new on this forum. Do I have to answer in the comment or in a new answer?


Forum|alt.badge.img
  • Author
  • June 29, 2016
david_r wrote:

You can either define your dictionary as a global variable:

global my_dict
my_dict = {1'a'2'b'3'c'}

Then in a different Python transformer you can access it like this:

global my_dict
my_value = my_dict[1]

Alternatively you can pass the dictionary as JSON strings from one transformer to another using the feature attributes.

To convert a dictionary "my_dict" to JSON and store it in the attribute "my_json":

feature.setAttribute('my_json', json.dumps(my_dict))

Then later on you can read the attribute "my_json" and convert it back to a dictionary:

my_dict = json.loads(feature.getAttribute('my_json))

I also added my_json in the Attributes to Expose. Is that right?


david_r
Celebrity
  • June 29, 2016
slerendu wrote:

I also added my_json in the Attributes to Expose. Is that right?

That's correct!


david_r
Celebrity
  • June 29, 2016
slerendu wrote:

By the way, I'm new on this forum. Do I have to answer in the comment or in a new answer?

You do as you feel :-)


david_r
Celebrity
  • Best Answer
  • June 29, 2016

Try this instead:

import json
import fmeobjects

class FeatureCreator(object):

    def __init__(self):
        pass

    def close(self):
        feature = fmeobjects.FMEFeature()
        myDict = {'Commune' : 'Tokyo'}
        feature.setAttribute('my_json', json.dumps(myDict))
        self.pyoutput(feature)

Notice how self.pyoutput(feature) always comes last.

Also notice that you have to import the json module.

If you attach a Logger after this PythonCreator you should get:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Logger_LOGGED'
Attribute(string): `fme_feature_type' has value `PythonCreator'
Attribute(string): `my_json' has value `{"Commune""Tokyo"}'
Geometry Type: Unknown (0)
===========================================================================

Hope this helps.


takashi
Influencer
  • June 29, 2016
slerendu wrote:

Thanks. But, I have a error in my log saying that the dictionnary isn't a string.

I checked printing the type of it. In the Creator, it is a string. But in the Caller, it became a NonType.

global myDict

 

class FeatureCreator(object):

 

def __init__(self):

 

pass

 

def close(self):

 

feature = fmeobjects.FMEFeature()

 

self.pyoutput(feature)

 

myDict = {'Commune' : 'Tokyo'}

 

feature.setAttribute('my_json', json.dumps(myDict))

 

print json.dumps(myDict)

 

print type(json.dumps(myDict))

Is that because I'm doing it in a method in a class?

Hi @slerendu, found two issues.

  • A global variable should be declared in the method definition that refers to the variable. In this case, you have to declare the 'myDict' global variable in the 'close' method.

  • The feature should be output AFTER assigning a value to the global variable. If the feature was output BEFORE assigning a value to the variable, its instance haven't been created yet when the feature arrived to the next PythonCaller.

takashi
Influencer
  • June 29, 2016
slerendu wrote:

Thanks. But, I have a error in my log saying that the dictionnary isn't a string.

I checked printing the type of it. In the Creator, it is a string. But in the Caller, it became a NonType.

global myDict

 

class FeatureCreator(object):

 

def __init__(self):

 

pass

 

def close(self):

 

feature = fmeobjects.FMEFeature()

 

self.pyoutput(feature)

 

myDict = {'Commune' : 'Tokyo'}

 

feature.setAttribute('my_json', json.dumps(myDict))

 

print json.dumps(myDict)

 

print type(json.dumps(myDict))

Is that because I'm doing it in a method in a class?

In addition, if you save the dictionary into a feature attribute as a JSON document, it's not necessary to use a global variable. See @david_r's answer.


Forum|alt.badge.img
  • Author
  • June 29, 2016
david_r wrote:

Try this instead:

import json
import fmeobjects

class FeatureCreator(object):

    def __init__(self):
        pass

    def close(self):
        feature = fmeobjects.FMEFeature()
        myDict = {'Commune' : 'Tokyo'}
        feature.setAttribute('my_json', json.dumps(myDict))
        self.pyoutput(feature)

Notice how self.pyoutput(feature) always comes last.

Also notice that you have to import the json module.

If you attach a Logger after this PythonCreator you should get:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Logger_LOGGED'
Attribute(string): `fme_feature_type' has value `PythonCreator'
Attribute(string): `my_json' has value `{"Commune""Tokyo"}'
Geometry Type: Unknown (0)
===========================================================================

Hope this helps.

Perfect. Thanks a lot.

Someone at my place told me that I can create my dictionnary in a startup python script. Is that a correct use? I find the json method cleaner.

What do you think?


david_r
Celebrity
  • June 29, 2016
slerendu wrote:

Perfect. Thanks a lot.

Someone at my place told me that I can create my dictionnary in a startup python script. Is that a correct use? I find the json method cleaner.

What do you think?

Apples and oranges.

If the dictionary stays the same during the entire translation, I'd just make it a global variable or something like that. You can create a global variable wherever you want, basically, including in a startup script.

If the dictionary is feature specific, I'd go the JSON route.


Forum|alt.badge.img
  • Author
  • June 29, 2016
david_r wrote:

Apples and oranges.

If the dictionary stays the same during the entire translation, I'd just make it a global variable or something like that. You can create a global variable wherever you want, basically, including in a startup script.

If the dictionary is feature specific, I'd go the JSON route.

Thanks, it's clearer now.


Forum|alt.badge.img
  • Author
  • June 29, 2016
takashi wrote:

Hi @slerendu, found two issues.

  • A global variable should be declared in the method definition that refers to the variable. In this case, you have to declare the 'myDict' global variable in the 'close' method.

  • The feature should be output AFTER assigning a value to the global variable. If the feature was output BEFORE assigning a value to the variable, its instance haven't been created yet when the feature arrived to the next PythonCaller.

Thanks for your answer. My problem was indeed the feature output.


Forum|alt.badge.img
  • Author
  • June 29, 2016
takashi wrote:

In addition, if you save the dictionary into a feature attribute as a JSON document, it's not necessary to use a global variable. See @david_r's answer.

When you say global variable, you mean "global myDict" in the PythonCreator or in the startupPythonScript?


takashi
Influencer
  • June 29, 2016
slerendu wrote:

When you say global variable, you mean "global myDict" in the PythonCreator or in the startupPythonScript?

I thought that you needed to define the global variable in the PythonCreator since I found the declaration within your script. However global variables can be defined anywhere according to your requirement. All depends on what you want to do with scripting ;)


Forum|alt.badge.img
  • Author
  • June 29, 2016
takashi wrote:

I thought that you needed to define the global variable in the PythonCreator since I found the declaration within your script. However global variables can be defined anywhere according to your requirement. All depends on what you want to do with scripting ;)

Ok, thanks :-)


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