2015-03-01

Create Schema Features with Python Script

Pythoスクリプトによるスキーマフィーチャーの作成

From this thread.
このスレッドから。
Community Answers > Oracle Spatial to SHAPE

In many cases, you can use the Schema (Any Format) reader to read schemas of source feature types from any format dataset. Schema features contains "attriubte{}" list, it can be used to configure dynamic schema with this method.
"Destination Schema is Derived from List Attributes"
多くの場合には、Schema (Any Format)リーダーを使って、どんなフォーマットでも、そのデータセットからソースフィーチャータイプのスキーマを読むことができます。スキーマフィーチャーは "attribute{}" リストを持っており、次の方法によってダイナミックスキーマを設定するのに使えます。
"Destination Schema is Derived from List Attributes"

However, in the case where the feature type (table) names will be determined at each run-time (i.e. they are unknown when creating the workspace), you cannot use the Schema reader since the feature types cannot be set to the reader beforehand.
しかし、フィーチャータイプ(テーブル)名が実行時に決定されるような場合(つまり、ワークスペース作成時にはそれらが未知である場合)には、フィーチャータイプをあらかじめ設定することができないため、Schemaリーダーを使うことができません。

In such a case, I think a Python script is an effective solution. fmeobjects.FMEUniversalReader class provides the functionality equivalent to the Reader in Workbench.
そのような場合には、Pythonスクリプトが効果的だと思います。fmeobjects.FMEUniversalReaderクラスが、ワークベンチのリーダーに相当する機能を提供します。
=====
Note: Safe is planning to do enhancement regarding schema reading functionality in the near future. This Python approach could be unnecessary after the enhancement has been done.
See also Dale's comment.
注: Safe社は近い将来におけるスキーマ読込に関する機能強化を計画しています。それが実現すると、このPythonによるアプローチは不要になるかも知れません。
デールさんのコメントも参照してください。
=====

For example, if the source feature type (e.g. Oracle Non-spatial database table) names will be given by an input feature which contains an attribute (e.g. "table_list") storing them in comma-delimited format, a PythonCaller with this script creates schema features for each table.
例えば、ソースフィーチャータイプ(例: Oracle Non-spatial データベーステーブル)名が、それらをカンマ区切り形式の属性(例: "table_list")として持つ入力フィーチャーによって与えられる場合には、次のスクリプトを設定したPythonCallerが各テーブルに対応するスキーマフィーチャーを作成します。
-----
class SchemaReader(object):
    def input(self, feature):
        # Create SCHEMA reader.
        # Set comma-delimited feature type (table) names to "IDLIST" directive.
        directives = ['IDLIST', feature.getAttribute('table_list')]
        reader = fmeobjects.FMEUniversalReader('SCHEMA', False, directives)
     
        # Open dataset.
        # The parameter setting is an example for ORACLE_NONSPATIAL format.
        # Required parameters other than "REAL_FORMAT" are different
        # depending on the real format.
        # See "Mapping File Directives" section in the help documentation
        # on the real format to learn more about the format specific parameters.
        dataset = <service name>
        parameters = [
            'REAL_FORMAT', 'ORACLE_NONSPATIAL',
            'USER_NAME', <user name>,
            'PASSWORD', <password>,
        ]
        reader.open(dataset, parameters)
     
        # Read and output schema features.
        while True:
            schema = reader.read()
            if schema == None:
                break
            self.pyoutput(schema)
         
        # Close the dataset.
        reader.close()

-----

It's simple and efficient, but I noticed that FME will write all the parameter values including password into the log file. For higher security, it might be better to create a format specific reader, rather than the Schema reader.
In this case, you will have to create the "attribute{}" with the script.
これは簡単で効率的ですが、FMEは、パスワードを含む全てのパラメーターの値をログファイルに書き込むことに気がつきました。より高いセキュリティのためには、Schemaリーダーではなく、フォーマット固有のリーダーを作成する方が良いかも知れません。
その場合、"attribute{}"はスクリプトで作成する必要があります。
-----
class SchemaReader(object):      
    def input(self, feature):
        # Create ORACLE_NONSPATIAL reader.
        # Set comma-delimited feature type (table) names to "IDLIST" directive.
        directives = ['IDLIST', feature.getAttribute('table_list')]
        reader = fmeobjects.FMEUniversalReader('ORACLE_NONSPATIAL', False, directives)
     
        # Open dataset.
        # The parameter setting is an example for ORACLE_NONSPATIAL format.
        # Required parameters are different depending on the format.
        # See "Mapping File Directives" section in the help documentation
        # on the real format to learn more about the format specific parameters.
        dataset = <service name>
        parameters = [
            'USER_NAME', <user name>,
            'PASSWORD', <password>,
        ]
        reader.open(dataset, parameters)
     
        # Read and output schema features.
        while True:
            schema = reader.readSchema()
            if schema == None:
                break
         
            # Set Feature Type Name.
            schema.setAttribute('fme_feature_type_name', schema.getFeatureType())
         
            # Create "attribute{}".
            for i, name in enumerate(schema.getSequencedAttributeNames()):
                type = schema.getAttribute(name)
                schema.setAttribute('attribute{%d}.name' % i, name)
                schema.setAttribute('attribute{%d}.fme_data_type' % i, type)
             
            # Ouput Schema Feature.
            self.pyoutput(schema)
         
        # Close the dataset.
        reader.close()
-----

See here to learn more about the FMEUniversalReader class and its methods.
FMEUniversalReaderクラスとそのメソッドの詳細についてはここを参照してください。
Python FME Objects API Reference

Although the example above is for the ORACLE_NONSPATIAL format, I think the same mechanism can also be applied to any other formats.
上の例はORACLE_NONSPATIALフォーマット用ですが、同じ仕組みは他のすべてのフォーマットにも適用できると思います。

FME 2015.0 build 15253

2 comments:

  1. Hi Takashi, Good work on this. We have just checked into the FME 2015.1 betas an extension to the FeatureReader which will produce schema features directly from a reader, and because the FeatureReader can get parameters from the features coming by, you can control the tables that will be returned. There have also been changes to the Feature Type Properties to make it easier to use the Schema Features to define output schema as well. We're still working on all this but it will open up some powerful opportunities.

    ReplyDelete
  2. Hi Dale, That's a wonderful news. It will make dynamic workflow implementation easier and more flexible. I'm looking forward to FME 2015.1 release!
    Thanks for the information.

    ReplyDelete