実行環境 関連リンクと過去記事 PostgreSQL用の汎用ウェブアクセス関数を、PL/Pythonで作成 作った関数のテスト(以上、昨日) (3)WebAPIの例として、MediaWiki APIからデータを取得(1月7日) (4)関数の改良(ⅰ)JSONを処理してpageidを直接返す(1月8日) (5)関数の改良(ⅱ)複数行に対するウェブアクセスを、ウィンドウ関数で1回にまとめる(1月9日、終)
Contents


PL/Pythonで作ったウェブアクセス関数を、PL/v8から使う

他のPostgreSQL組み込み言語と同様、PL/v8も便利なデータベースアクセスの仕組みを持ってます。例えば ↓ のようにplv8.executeという関数に任意をクエリを入れて実行すると、結果がJSON配列に。昨日作ったPL/Pythonのウェブアクセス関数を実行するのも一つのクエリなので、PL/v8から簡単に使えるというわけ。
var res = plv8.execute('任意のクエリ'); -- 結果がJSON配列で返る


昨日の自作関数を使う前に ↓ 適当なクエリを打って結果の取り出し方をテスト。無名コードブロックを使い、クエリ結果の全体と一部をplv8.elog関数でメッセージとして表示しました。結果全体が一つの配列で、DBから返ってきた1行ずつが配列の各要素。その中が「列名:値」のオブジェクトになってます。
do language plv8 $$
    var sql = 'select * from pg_extension', -- 適当なクエリ
        res = plv8.execute(sql);
    plv8.elog(INFO, '結果全体(配列)', JSON.stringify(res), '\n');
    plv8.elog(INFO, '結果の1行目', JSON.stringify(res[0]), '\n');
    plv8.elog(INFO, '結果の1行目の特定の列', JSON.stringify(res[0]['extname']));
$$;
INFO:  結果全体(配列) [{"extname":"plpgsql","extowner":10,"extnamespace":11,"extr
elocatable":false,"extversion":"1.0","extconfig":null,"extcondition":null},{"extn
ame":"plv8","extowner":10,"extnamespace":11,"extrelocatable":false,"extversion":"
1.4.2","extconfig":null,"extcondition":null},{"extname":"plpython3u","extowner":1
0,"extnamespace":11,"extrelocatable":false,"extversion":"1.0","extconfig":null,"e
xtcondition":null}]

INFO:  結果の1行目 {"extname":"plpgsql","extowner":10,"extnamespace":11,"extreloc
atable":false,"extversion":"1.0","extconfig":null,"extcondition":null}

INFO:  結果の1行目の特定の列 "plpgsql"
DO

PL/v8から
昨日作ったウェブアクセス関数を使うのも同様で、引数に任意のURLを入れてクエリを作りplv8.executeに渡せばOK。ただし追加的な処理が二つあります。それは

実際にHTMLコンテンツをPL/v8で取得すると ↓ こんな感じ。昨日の記事のソースです。Windowsのコンソールとpsqlの組み合わせではUTF-8の多言語テキストをまともに表示できないので
(関連記事720日)ここだけpgAdminのクエリツールを使いました。
do language plv8 $$
    var url = 'http://kenpg.bitbucket.org/blog/201601/04.html',
        enc = 'utf8',
        sql = "select convert_from(plpy_urlopen('" + url + "'), '" + enc + "')",
        res = plv8.execute(sql),
        htm = res[0]['convert_from'];
    plv8.elog(INFO, typeof htm);
    plv8.elog(INFO, htm);
$$;


HTMLでなくWebAPIJSONの例。Wikipediaの記事を検索できるMediaWiki APIを使い、タイトル検索ワードを変数keywordに入れてリクエストしてます。結果のJSONをサクッと確認するにはJSON.stringify関数が便利。今回は英語版MediaWikiを対象にしましたが、日本語を含みWindowsで行うなら上と同様にpgAdminを使って下さい。
do language plv8 $$
    var keyword = 'postgres',
        url = 'https://en.wikipedia.org/w/api.php?action=query&format=json'
            + '&titles=' + keyword,
        enc = 'utf8',
        sql = "select convert_from(plpy_urlopen('" + url + "'), '" + enc + "')",
        res = plv8.execute(sql),
        dat = JSON.parse(res[0]['convert_from']);
    plv8.elog(INFO, typeof dat);
    plv8.elog(INFO, dat);
    plv8.elog(INFO, JSON.stringify(dat));
$$;

INFO:  object
INFO:  [object Object]
INFO:  {"batchcomplete":"","query":{"normalized":[{"from":"postgres","to":"Postgr
es"}],"pages":{"290657":{"pageid":290657,"ns":0,"title":"Postgres"}}}}
DO

上を、今回PL/v8からWebAPIJSONデータを取得&処理するテンプレにします。明日以降は、DO文(無名コードブロック)でなくちゃんとストアド関数をつくり、データベースとMediaWiki APIを連携させる予定。