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