2014-12-13

Read Schemas from Database with Schema (Any Format) Reader

Schema (Any Format) リーダーでデータベースからスキーマを読む

I mentioned a quick way to create a look-up table for the Dynamic Schema in this thread.
このスレッドでダイナミックスキーマ用のルックアップテーブルを作成する簡単な方法に言及しました。
Community Answers > Can you use SchemaMapper or BulkAttributeRenamer with a dynamic schema writer?

Related articles 関連記事:
FMEpedia > Dynamic Workflow Tutorial: Destination Schema is Derived from a Lookup Table
This Blog > Common Table for SchemaMapper and Dynamic Schema

The Schema (Any Format) reader followed by a ListExploder can be used to create a table that contains feature type names, attribute names and their data type names of source feature types. It will cut down your time and effort for creating a look-up table for the Dynamic Schema.
It's a wisdom of a lazy person who doesn't want to move his/her hands :)
Schema (Any Format) リーダーとListExploderは、ソースフィーチャータイプのフィーチャータイプ名、属性名、およびそれらのデータ型名を含むテーブルを作成するのに使えます。これは、ダイナミックスキーマ用のルックアップテーブルを作成するための時間と労力を削減するでしょう。
手を動かしたくない怠け者の智恵です (^^)

When adding the Schema reader, you need to specify the source dataset to its Dataset field.
Schemaリーダーを追加する際、Datasetフィールドにソースデータセットを指定する必要があります。













If the physical form of the source dataset was a file, you can select the file with the general Select File dialog box. And if it was a folder (e.g. ESRI File Geodatabase), you can enter the folder path into the Dataset field directly.
ソースデータセットの物理的な形態がファイルである場合は、通常のファイル選択ダイアログボックスによって選択することができます。 また、フォルダ(例えばESRI File Geodatabase)である場合は、Datasetフィールドにフォルダパスを直接入力することができます。

So then, how can you set a database as its source dataset?
では、ソースデータセットとしてデータベースを設定するには?

The Schema reader doesn't have parameters for database connection, such as host name, port number, user name, password. Even though you specified the database name to the Dataset, naturally you cannot configure the connection to the database.
Schemaリーダーには、ホスト名、ポート番号、ユーザー名、パスワードなどのデータベース接続のためのパラメーターがありません。Datasetにデータベース名を指定したとしても、当然のことながらデータベースとの接続を確立することはできません。

To read schemas from a database, add the database format specific reader to the workspace and set its parameters (host name, port number etc.) properly.
And then, for the Schema reader,
- set the "Source Dataset" parameter to the database name,
- set the "Input Format" parameter to the format name explicitly.
After this, the Schema reader will be able to connect to the database, and to read schemas of the tables, since it can refer to configuration of another reader in the same workspace.
データベースからスキーマを読むには、ワークスペースにそのデータベースフォーマット固有のリーダーを追加し、パラメーター(ホスト名、ポート番号など)を適切に設定してください。
そして、Schemaリーダーについては、
- "Source Dataset"パラメーターにデータベース名を設定し,
- "Input Format"パラメーターにフォーマット名を明示的に設定します。
Schemaリーダーは同じワークスペース内の他のリーダーの設定を参照できるので、この後、データベースに接続してテーブルのスキーマを読むことができるようになります。

This is an example of the configuration to read schemas from a PostgreSQL database.
これはPostgreSQLデータベースからスキーマを読み込むための設定例です。

























You can select feature types (tables) with the "Feature Types to Read" parameter of the POSTGRES reater. If you don't need to read data from the database, you can set the "Max Features to Read" parameter to 1 (0 seems to be invalid unfortunately).
フィーチャータイプ(テーブル)は、POSTGREASリーダーの"Feature Types to Read"パラメーターで選択できます。データベースからデータを読む必要がなければ、"Max Features to Read"パラメーターを1に設定できます(残念ながら0は無効なようです)。

I added the POSTGRES reader as a usual reader in the above example, but you can also add it as a Workspace Resource (Menu: Readers > Add Reader as Resource).
This may be better if you don't need to read the actual data.
上の例ではPOSTGRESリーダーは通常のリーダーとして追加しましたが、ワークスペースリソースとして追加することもできます(Menu: Readers > Add Reader as Resource)。
実際のデータを読む必要がない場合は、この方が良いかも知れません。

















In addition, the "referring to another reader configuration" can also be applied to read schemas from a web dataset like the Google Maps Engine.
加えて、この「他のリーダーの設定を参照する」機能は、Google Maps Engineなどのウェブデータセットからスキーマを読み込むのにも応用できます。

FME 2014 SP4 build 14433

Wow, FME 2014 SP5 build 14440 has been released!
おぉ、FME 2014 SP5 build 14440 がリリースされている!
The Safe Software Blog > FME Service Packs: The Dawning of the Age of .0

=====
Scripting is also possible but I would not recommend to use it in a practical workspace.
Just a self-training concerning Python FME Objects API.
スクリプトも可能ですが、実際のワークスペースで使うことはお勧めしません。
Python FME Objects API に関するトレーニングです。
-----
# Script Example for PythonCreator, 2014-12-14 Updated
import fmeobjects
class PostgresSchemaReader(object):
    def close(self):
        directives = [
            'IDLIST', 'table1,table2,table3',
        ]
        parameters = [
            '_HOST', 'localhost',
            '_PORT', '5432',
            '_USER_NAME', 'username',
            '_PASSWORD', 'foobar',
        ]
        reader = fmeobjects.FMEUniversalReader('POSTGRES', False, directives)
        reader.open('test', parameters)
        while True:
            schema = reader.readSchema()
            if schema == None:
                break
            featureTypeName = schema.getFeatureType()
            schema.setAttribute('fme_feature_type_name', featureTypeName)
            for i, name in enumerate(schema.getSequencedAttributeNames()):
                fmeDataType = schema.getAttribute(name)
                nativeDataType = schema.getAttribute('*%s' % name)
                schema.setAttribute('attribute{%d}.name' % i, name)
                schema.setAttribute('attribute{%d}.fme_data_type' % i, fmeDataType)
                schema.setAttribute('attribute{%d}.native_data_type' % i, nativeDataType)
            self.pyoutput(schema)
        reader.close()
-----

2014-12-12

3/2 returns 1 or 1.5?

3/2は1と1.5のどちらを返すか?

The answer is 1, in FME 2014 and earlier.
答は1です。FME 2014以前では。

In almost all the programming languages e.g. C, Python 2.x, Tcl, the / operator returns an integer value if both operands are integers. As well, 3/2 entered with the Arithmetic Editor of FME Workbench has returned 1 for a long time. I think the manner of math operations of FME has been basically inherited from C.
3/2 returns 1, 3.0/2, 3/2.0, or 3.0/2.0 returns 1.5.
C, Python 2.x, Tclなどのほとんど全てのプログラミング言語では、/演算子は、両オペランドが整数のときは整数値を返します。同様に、FMEワークベンチの数式エディタで入力された3/2は、長い間1を返してきました。FMEにおける算術演算の仕方は、基本的にはCから継承されているのだと思います。
3/2は1を返し、3.0/2, 3/2.0 または 3.0/2.0は1.5を返します。
=====
2014-12-17:
Added "2.x" to Python since 3/2 returns 1.5 in Python 3.
See also the comments in this article.
Python 3では、3/2は1.5を返すので、Pythonに「2.x」を追記しました。
この記事についてのコメントも参照してください。
=====

In some cases, the rule "int/int returns int" can be used effectively.
For example, 0-based sequential index of a grid cell can be converted to row, column index with these expressions.
row index = sequential index / number of columns
column index = sequential index % number of columns
あるケースでは、この「整数/整数は整数を返す」というルールは効果的に使えます。
例えば、次の式により、グリッドセルに与えられた0から始まる連番を行, 列のインデクスに変換することができます。
行インデクス = 連番 / 列数
列インデクス = 連番 % 列数













On the other hand, however, it's also a fact that the rule has brought a confusion to many users who expect 3/2 returns 1.5. If you don't know the rule, you will have to consume long time to find the issue in the workspace. I've called it "integer division trap".
しかし一方では、このルールが、3/2が1.5を返すことを期待する多くのユーザーに混乱をもたらしてきたのも事実です。このルールを知らなければ、ワークスペースにおける問題点を見つけるのに長い時間を費やさなければなりません。私はこれを「整数除算のワナ」と呼んできました。

Now, I got an important information that says the rule will be changed. The / operator in FME 2015 will always perform floating point division, even if both operands are integers.
さて、このルールが変更されるという重要な情報を得ました。FME 2015における/演算子は、両オペランドが整数であっても、常に小数点数の除算を行うことになるのです。

Yes. The answer will be 1.5, in FME 2015.
そう。FME 2015では、答は1.5になります。

I was surprised when I heard it from Safe, and it was hard to accept such a radical change, honestly. Although I now understand it's reasonable for many users, I'm afraid of side-effects against existing workspaces.
Safe社からこれを聞いたときは驚き、正直なところ、そのような過激な変更は受け入れ難いものでした。今は多くのユーザーにとって妥当なことであると理解していますが、既存のワークスペースに対する副作用は心配です。

In my quick test, math expressions in existing workspaces created with FME 2014 were performed in the current rule "int/int returns int" when I ran it with FME 2015 Workbench.
It's good.
But, if you once open the expression with the Arithmetic Editor of FME 2015 and closed the transformer parameters dialog with OK button, the rule will be changed to the new one "/ operator always performs floating point division".
We need to be aware it.
簡単なテストをしたところ、FME 2014で作成した既存のワークスペースにおける数式は、FME 2015のワークベンチで実行した場合でも現在のルール「整数/整数は整数を返す」で行われました。
これは良い。
ただ、FME 2015の数式エディタでその式を開き、トランスフォーマーのパラメータ設定ダイアログボックスをOKボタンで閉じると、新しいルール「/演算子は常に小数点数の除算を行う」に変更されます。
これには注意が必要です。

=====
2014-12-18:
As Mark@Safe commented, when you open a math expression containing / operator that was entered with FME 2014 (or earlier) with the Arithmetic Editor in FME 2015, this large warning message will appear.
Safe社マークさんがコメントしたように、FME 2014以前で入力された / 演算子を含む数式を FME 2015 の数式エディタで開いたときは、次のような大きな警告メッセージが表示されます。













However, it seems to appear only when opening the expression with the Arithmetic Editor.
If you modified the expression without using the Arithmetic Editor, or edited other parameter values, and then you close the transformer parameters dialog with [OK] button, the division behavior change will be applied to the transformer without the message.
I hope that such an implicit change will not happen.
Tested with FME 2015 beta build 15230.
しかし、これはその式を数式エディタで開くときだけ表示されるようです。
数式エディタを使わずにその式を修正したり、他のパラメータを編集したりしてからトランスフォーマーのパラメーター設定ダイアログボックスを [OK] ボタンで閉じると、そのトランスフォーマーについて、メッセージなしで除算の動作の変更が適用されます。
そのような暗黙の変更は起こらないことを望みます。
FME 2015 ベータ版 build 15230 でテストしました。
=====

In addition, I believe that the rule in Python and Tcl scripts will not change. Absolutely?
なお、Python、Tclスクリプトにおけるこのルールは変わらないはずです。もちろんですよね?
=====
2014-12-15
...was not "absolutely". The / operator in Python 3 has changed its behavior (3/2 returns 1.5). See also David's comment.
... 「絶対に」ということはありませんでした。Python 3 の / 演算子の動作には変更があります(3/2は1.5を返す)。ディビッドさんのコメントも参照してください。

Note: FME 2015 uses Python 2.7, at least in beta build 15225.
注: FME 2015はPython 2.7を使用しています、少なくともベータ版ビルド15225では。
=====

FME 2014 SP4 build 14433, FME 2015 Beta build 15225

2014-12-06

Regular Expressions and FME String Functions

正規表現とFME文字列関数

From this thread.
このスレッドより。
Community Answers > Stringrepalcer

The requirement can be summarized as:
Split a string consisting of space-separated parts; extract each first four characters from the first and the second parts; concatenate them with a comma delimiter.
要求は次のように要約できます。
空白で区切られたいくつかの部分で構成された文字列を分割し、1番目と2番目の部分からそれぞれ先頭の4文字を抽出し、それらをカンマ区切りで連結する。
e.g. 例えば:
Input: "54960000.0 643600000.63 0.0"
Output: "5496,6436"

As a basic approach, it can be realized with an AttributeSplitter, two SubstringExtractors, and a StringConcatenator.
基本的なアプローチとして、これは一つのAttributeSplitter、二つのSubstringExtractor、一つのStringConcatenatorで実現できます。











Of course this approach is good, but the question is how to do that with one step.
My first inspiration was the StringReplacer with this regular expression.
もちろんこのアプローチで良いのですが、質問は、これを一つのステップで行うにはどうするか、です。
最初のインスピレーションはこの正規表現を使ったStringReplacerでした。
-----
^([0-9]{4})[^\s]*\s+([0-9]{4}).*$
-----

Regular expressions are very flexible. I think that a regular expression can be used in almost all the cases where you need to extract some parts of a character string based on specific patterns.
正規表現は非常に柔軟で、文字列から特定のパターンに該当する部分を抽出したいときには、ほとんど全てのケースで使えると思います。

However, in some cases, the FME String Functions could also be convenient.
In the case above, if the original string is stored by a feature attribute called "coord", this expression written in the Value column of an AttributeCreator returns the required result.
しかし、あるケースでは、FME文字列関数が便利なこともあります。
上記の場合、オリジナルの文字列が"coord"という属性に格納されているならば、AttributeCreatorのValue列に書かれた次の式は必要な結果を返します。
-----
@Left(@Value(coord),4),@Left(@GetWord(@Value(coord),1),4)
-----

@Left function returns first N characters of specified string (N is the number of characters);
@GetWord function returns the Nth part (N is 0-based index) of space-separated parts.
@Left関数は指定された文字列の最初のN文字を返し(Nは文字数)、
@GetWord関数は空白で区切られた第N番目(Nは0から始まるインデクス)の部分を返します。

=====
2014-12-08: Alternatively, @ReplaceRegEx function can also be used.
あるいは、@ReplaceRegEx関数も使えます。
-----
@ReplaceRegEx(@Value(coord),^([0-9]{4})[^\s]*\s+([0-9]{4}).*$,"\1,\2")
=====

The FME String Functions are relatively easy to understand, so I think it's worth to consider using them in many cases.
FME文字列関数は比較的分かり易いので、多くの場合で検討に値すると思います。
FME Workbench Transformers > String Functions

But, more than enough is too much...
ただし、過ぎたるは及ばざるがごとし。。。
FME String Functions


Addition.
If you prefer scripting, assuming "coord" is storing a space-separated strings:
おまけ。
スクリプトを好むならば、"coord"が空白区切りの文字列を格納していると仮定して:

Tcl script examples for the "Value" in an AttributeCreator (enter with the Arithmetic Editor)
AttributeCreator "Value"のためのTclスクリプト例 (Arithmetic Editorで入力)
-----
[regsub {^([0-9]{4})[^\s]*\s+([0-9]{4}).*$} "@Value(coord)" {\1,\2}]
-----
[format {%s,%s} [string range "@Value(coord)" 0 3] [string range [lindex "@Value(coord)" 1] 0 3]]
-----

Script examples for the "Tcl Expression" in a TclCaller
TclCaller "Tcl Expression"のためのスクリプト例
-----
return [regsub {^([0-9]{4})[^\s]*\s+([0-9]{4}).*$} [FME_GetAttribute coord] {\1,\2}]
-----
return [format {%s,%s} [string range [FME_GetAttribute coord] 0 3] [string range [lindex [FME_GetAttribute coord] 1] 0 3]]
-----

Script examples for a PythonCaller
PythonCallerのためのスクリプト例
-----
import re
def processFeature(feature):
    src = feature.getAttribute('coord')
    feature.setAttribute('coord', re.sub(r'^([0-9]{4})[^\s]*\s+([0-9]{4}).*$', r'\1,\2', src))
-----
def processFeature(feature):
    src = feature.getAttribute('coord')
    feature.setAttribute('coord', '%s,%s' % (src[:4], src.split(' ')[1][:4]))
-----
and so on.
などなど。

In fact, the StringReplacer uses the Tcl command "regsub" internally.
実のところ、StringReplacerは内部でTclコマンド"regsub"を使っています。

Déjà vu (already seen) :-)
デジャヴ (^^)
Community Answers > Leading zeros
Poor Cat

=====
2014-12-08: Forgot the JavaScriptCaller transformer.
JavaScriptCallerトランスフォーマーを忘れていました。
-----
var src = fme_get_attribute("coord");
fme_set_attribute("coord", src.replace(/^([0-9]{4})[^\s]*\s+([0-9]{4}).*$/, "$1,$2"));
-----
var src = fme_get_attribute("coord");
fme_set_attribute("coord", src.substr(0, 4) + "," + src.split(' ')[1].substr(0, 4));
-----
hmm... the JavaScriptCaller may be convenient for string operations, although I have never used yet in a practical workspace.
... but Japanese characters written in a script seems not to be interpreted correctly. Unfortunate.
うむむ。実際のワークスペースではまだ一度も使ったことはないけど、JavaScriptCallerは文字列の操作をするのに便利かも知れない。
... しかし、スクリプト中に書かれた日本語文字は正しく解釈されないみたいだ。残念。
=====

FME 2014 SP4 build 14433