11.6.2 pyqEvalファンクション(オンプレミス・データベース)

このトピックでは、オンプレミスOracle Databaseで使用されるpyqEvalファンクションについて説明します。pyqEvalファンクションは、データを明示的に取得するか、関数について外部データが自動的にロードされるユーザー定義Python関数を実行します。

PAR_LSTパラメータを使用して、引数をPython関数に渡すことができます。

pyqEvalファンクションは、データベースからデータを自動的には受け取りません。Python関数は、使用するデータを生成するか、Oracle Database、その他のデータベース、フラット・ファイルなどのデータ・ソースからデータを明示的に取得します。

Python関数は、booleandictfloatintliststrtupleまたはpandas.DataFrameオブジェクトを返すことができます。OUT_FMTパラメータを使用して、返される値の形式を定義できます。

構文

pyqEval(
    par_lst VARCHAR2,
    out_fmt VARCHAR2,
    scr_name VARCHAR2,
    scr_owner VARCHAR2 DEFAULT NULL)

パラメータ

パラメータ 説明

PAR_LST

SCR_NAMEパラメータで指定されたユーザー定義Python関数に渡す追加パラメータが含まれるJSON文字列。oml_で始まる特殊な制御引数は、SCR_NAMEで指定された関数に渡されるのではなく、関数の呼出し前後の動作を制御します。

たとえば、入力データ型をpandas.DataFrameとして指定するには、次を使用します。

'{"oml_input_type":"pandas.DataFrame"}'

OUT_FMT

ファンクションによって返される出力の形式。次のいずれかになります。

  • ファンクションによって返された表の列名およびデータ型を指定するJSON文字列。イメージ・データは破棄されます。
  • プロトタイプとして使用する表またはビューの名前。別のユーザーが所有する表またはビューを使用する場合は、<owner name>.<table/view name>という形式を使用します。指定された表またはビューに対する読取りアクセス権が必要です。
  • 文字列'XML'。返される表にXML文字列であるCLOBが含まれることを指定します。XMLには構造化データとイメージの両方が含まれる可能性があり、最初に構造化または半構造化のPythonオブジェクトが含まれ、続いてPython関数によって生成されたイメージが含まれます。
  • 文字列'PNG'。返される表に、Python関数によって生成されたイメージを格納するBLOBが含まれることを指定します。イメージはPNG表示のbase 64エンコーディングとして返されます。

SCR_NAME

OML4Pyスクリプト・リポジトリ内のユーザー定義Python関数の名前。

SCR_OWNER

登録済Pythonスクリプトの所有者。デフォルト値は「NULL」です。NULLの場合、ユーザーのスクリプト・リポジトリでPythonスクリプトを検索します。

戻り値

ファンクションpyqEvalは、OUT_FMTパラメータ値で指定された構造を持つ表を返します。

例11-15 pyqEvalファンクションの使用

この例では、Python関数を定義し、OML4Pyスクリプト・リポジトリに格納します。ユーザー定義Python関数に対してpyqEvalファンクションを呼び出します。

PL/SQLブロックで、pyqFun1という名前でスクリプト・リポジトリに格納される名前なしPython関数を作成します。

BEGIN
   sys.pyqScriptCreate('pyqFun1', 'func = lambda: "Hello World from a lambda!"',
                        FALSE, TRUE); -- V_GLOBAL, V_OVERWRITE
END;
/

pyqEvalファンクションを呼び出します。この関数は、ユーザー定義Python関数を実行し、結果をXMLとして返します。


SELECT name, value 
  FROM table(pyqEval(
             NULL,
             'XML',
             'pyqFun1'));

出力は次のようになります。


NAME  VALUE
----  --------------------------------------------------       
      <root><str>Hello World from a lambda!</str></root>

ユーザー定義Python関数を削除します。

BEGIN
  sys.pyqScriptDrop('pyqFun1');
END;
/ 

pyqFun2という名前でスクリプト・リポジトリに格納されるnumpy.ndarrayを返すPython関数を定義します。

BEGIN
  sys.pyqScriptCreate('pyqFun2',
    'def return_frame():
       import numpy as np
       import pickle
       z = np.array([y for y in zip([str(x)+"demo" for x in range(10)],
                      [float(x)/10 for x in range(10)],
                      [x for x in range(10)],
                      [bool(x%2) for x in range(10)],
                      [pickle.dumps(x) for x in range(10)],
                      ["test"+str(x**2) for x in range(10)])],
                    dtype=[("a", "U10"), ("b", "f8"), ("c", "i4"), 
                           ("d", "?"), ("e", "S20"), ("f", "O")])
       return z');
END;
/

ユーザー定義Python関数pyqFun2を実行するpyqEvalファンクションを呼び出します。

SELECT * 
  FROM table(pyqEval(
               NULL,
               '{"A":"varchar2(10)", "B":"number", 
                 "C":"number", "D":"number",
                 "E":"raw(10)", "F": "varchar2(10)" }',
                'pyqFun2'));

出力は次のようになります。


A                   B          C          D E                    F
---------- ---------- ---------- ---------- -------------------- ----------
0demo               0          0          0 80034B002E           test0
1demo        1.0E-001          1          1 80034B012E           test1
2demo        2.0E-001          2          0 80034B022E           test4
3demo        3.0E-001          3          1 80034B032E           test9
4demo        4.0E-001          4          0 80034B042E           test16
5demo        5.0E-001          5          1 80034B052E           test25
6demo        6.0E-001          6          0 80034B062E           test36
7demo        7.0E-001          7          1 80034B072E           test49
8demo        8.0E-001          8          0 80034B082E           test64
9demo        9.0E-001          9          1 80034B092E           test81

10 rows selected.

ユーザー定義Python関数を削除します。

BEGIN
  sys.pyqScriptDrop('pyqFun2');
END;
/