13.6.2 pyqEvalファンクション(オンプレミス・データベース)
このトピックでは、オンプレミスOracle Databaseで使用されるpyqEvalファンクションについて説明します。pyqEvalファンクションは、データを明示的に取得するか、関数について外部データが自動的にロードされるユーザー定義Python関数を実行します。
               
PAR_LSTパラメータを使用して、引数をPython関数に渡すことができます。
                  
pyqEvalファンクションは、データベースからデータを自動的には受け取りません。Python関数は、使用するデータを生成するか、Oracle Database、その他のデータベース、フラット・ファイルなどのデータ・ソースからデータを明示的に取得します。
                  
Python関数は、boolean、dict、float、int、list、str、tupleまたはpandas.DataFrameオブジェクトを返すことができます。OUT_FMTパラメータを使用して、返される値の形式を定義できます。 
                  
構文
pyqEval(
    par_lst VARCHAR2,
    out_fmt VARCHAR2,
    scr_name VARCHAR2,
    scr_owner VARCHAR2 DEFAULT NULL)
                  パラメータ
| パラメータ | 説明 | 
|---|---|
| 
                                 
                                  
  | 
                              
                                 
                                  
 たとえば、入力データ型を 
  | 
                           
| 
                                 
                                  
  | 
                              
                                 
                                  ファンクションによって返される出力の形式。次のいずれかになります。 
  | 
                           
| 
                                 
                                  
  | 
                              
                                 
                                  OML4Pyスクリプト・リポジトリ内のユーザー定義Python関数の名前。  | 
                           
| 
                                 
                                  
  | 
                              
                                 
                                  登録済Pythonスクリプトの所有者。デフォルト値は「NULL」です。NULLの場合、ユーザーのスクリプト・リポジトリでPythonスクリプトを検索します。  | 
                           
戻り値
ファンクションpyqEvalは、OUT_FMTパラメータ値で指定された構造を持つ表を返します。
                  
例13-17 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;
/