2016-08-12 12 views
1

RedshiftでPythonユーザー定義関数を学び始めています。私は明確にする必要があるいくつかの質問があります。Redshift Python UDFの各関数呼び出しでのインポート

CREATE OR REPLACE FUNCTION f_parse_url_query_string(url VARCHAR(MAX)) 
RETURNS varchar(max) 
STABLE 
AS $$ 
    from urlparse import urlparse, parse_qsl 
    import json 
    return json.dumps(dict(parse_qsl(urlparse(url)[4]))) 
$$ LANGUAGE plpythonu; 

これはimportsに関数が呼び出されたか、これは赤方偏移によってコンパイルされ、1つだけの時間をインポートするたびに実行するつもりです:私は次の関数を定義したと仮定すると?

私の2番目の質問は、可変データ型を返す方法があるかどうかです。たとえば、入れ子になったjsonフィールドの値を取得する関数を作成する場合、結果は文字列から整数またはブール値のいずれかになります。関数の戻り型について自動検出を作成する方法はありますか?

答えて

1

実行

はい、importは毎回実行されます。

これを回避する1つの方法は、関数のボラティリティとしてIMMUTABLEを使用することです。これによりRedshiftは与えられた入力値に対して関数の出力をキャッシュすることができます。これにより、将来同じ入力値に対してPython関数を実行する必要がなくなります。

戻り値

戻り値のデータ型が固定されており、変更することはできません。異なる関数名または異なる入力タイプに対して異なる戻り値を定義することができます(たとえば、整数を取り、整数を返し、同じ名前を持つ別の関数を定義しますが、文字列を返す文字列入力型出力として)。

また、異なる出力データ型を返す関数を使用することは非常に困難です。UDFを呼び出すSQL文は、変更されていない特定のデータ型を必要とします。

1

輸入

はいなし。 Redshiftは、udf実行環境をステートメント内で再利用します(トランザクション全体であってもおそらくテストしていません)。そのimport文を処理する際に関数が呼び出されるたびにimport文が処理されるのは間違いありませんが、cpythonはそのモジュールがすでにインポートされているかどうかを素早く確認し、既にインポートされているモジュールがあればそれを使用します。これらのような関数ローカル(遅い)インポートは、循環依存性の問題を回避するために頻繁に使用されるため、実行する必要があります。私はまた、次のような何かを行うことによって、UDF年代に世界的な初期化の不足を回避するためにこれを使用しました:

if '_cache' not in globals(): import thing globals()['_cache'] = thing.build_cache() return _cache.get(arg)

それは私がどこでもやるだろうな何かが、UDFはないのですが、これはまさに一般的ではありません-purpose code。

udf実行環境に関しては明らかに深刻であり、あまりにも重視するべきではありませんが、現実的にはすぐに実質的に変更することはほとんどありません。特定のプロセスがどれだけ長く存続するか/処理される行の数は保証されませんが、cpythonプロセス(とコンテナ)の作成は正確には安いものではありません。一列ごとに行うには重すぎます。彼らは分離のためにlxcに依存し、実行するための実際の(サンドボックスの場合)Linux環境を提供します(これは、ユーザーがインストールしたネイティブ拡張のためには本当に必要です)。それは、戻り値のデータ型は赤方偏移を変更することはできません本当ですが:)

戻り値

を掘るために気にする人のためにファイルシステム上に転がっても、いくつかのドキュメントがあります(今?)ANYELEMENTをサポートしています引数と戻り値の型の両方のデータ型。前の解で説明したように、戻り型の多態性はまだサポートされていないため、型指定された引数を必要としますが、返す型ごとに別々の関数を作成する必要はありません。

関連する問題