iakioの日記 RSSフィード

2008-05-13

複数行複数列を返すPL/pgSQL関数

| 21:43 | 複数行複数列を返すPL/pgSQL関数 - iakioの日記 を含むブックマーク はてなブックマーク - 複数行複数列を返すPL/pgSQL関数 - iakioの日記

はてなブログ

IN/OUTパラメータが導入されてからset return functionってどう書くのかいまいちわかってなかったので調べてみました。

OUTパラメータを使う(8.1くらい以降)

CREATE OR REPLACE FUNCTION hoge(OUT a integer, OUT b integer, OUT c integer)
RETURNS SETOF RECORD AS '
BEGIN
  SELECT 1, 2, 3 INTO a, b, c;
  RETURN NEXT;
  RETURN;
END
' LANGUAGE plpgsql;
SELECT * FROM hoge();

引数無しのRETURN NEXTを使うのがポイントのようです。

で、次の2つは伝統的な方法。

CREATE TYPEする

CREATE TABLEでもいいけど。

CREATE TYPE hoge_type AS (a integer, b integer, c integer);
CREATE OR REPLACE FUNCTION hoge()
RETURNS SETOF hoge_type AS '
DECLARE
  rec RECORD;
BEGIN
  SELECT 1 AS a, 2 AS b, 3 AS c INTO rec;
  RETURN NEXT rec;
  RETURN;
END
' LANGUAGE plpgsql;
SELECT * FROM hoge();

aliasを使う

RETURNS SET OF RECORDでも、SELECTする時に明示的に型指定することができます。

CREATE OR REPLACE FUNCTION hoge()
RETURNS SETOF RECORD AS '
DECLARE
  rec RECORD;
BEGIN
  SELECT 1 AS a, 2 AS b, 3 AS c INTO rec;
  RETURN NEXT rec;
  RETURN;
END
' LANGUAGE plpgsql;
=> SELECT * FROM hoge() AS (a integer, b integer, c integer);
 a | b | c
---+---+---
 1 | 2 | 3
(1 row)

SkyToolsについて調べる(2) - ログの出力

| 07:27 | SkyToolsについて調べる(2) - ログの出力 - iakioの日記 を含むブックマーク はてなブックマーク - SkyToolsについて調べる(2) - ログの出力 - iakioの日記

そういえば書き忘れてましたが私はskytools-2.1.5のコードを見ながらこれを書いてました。と思ったら2.1.6がリリースされているのに気付いてませんでした。というわけで今回から2.1.6を見ながら書きます。あとOSFreeBSD 6.3 Releaseです。

skytools-2.1.6はFreeBSDでgmake installするとエラーになるので、Makefile内の"make"を"$(MAKE)"に書き換えておきましょう。このバグは修正済のようです*1

--- Makefile.orig       2008-04-05 22:24:51.000000000 +0900
+++ Makefile    2008-05-12 22:26:57.000000000 +0900
@@ -38,7 +38,7 @@

 python-install: config.mak modules-all
        $(PYTHON) setup.py install --prefix=$(prefix) --root=$(DESTDIR)/
-       make -C doc DESTDIR=$(DESTDIR) install
+       $(MAKE) -C doc DESTDIR=$(DESTDIR) install

 python-install python-all: python/skytools/installer_config.py
 python/skytools/installer_config.py: python/skytools/installer_config.py.in config.mak
@@ -78,7 +78,7 @@
        debuild -uc -us -b

 tgz: config.mak clean
-       make -C doc man
+       $(MAKE) -C doc man
        $(PYTHON) setup.py sdist -t source.cfg -m source.list

 debclean: distclean

今回はskytools.DBScriptからのログの出力について調べてみますが、基本的にはPythonのloggingモジュールそのまんまです。

ログを出力する方法

self.logがLoggerオブジェクトなので、self.log.info()とかself.log.error()とかでログを出力できます。前のプログラムをちょっとマトモにしてみると、

import sys
import skytools

class Hello(skytools.DBScript):
    def __init__(self, args):
        skytools.DBScript.__init__(self, 'hello', args)

    def work(self):
        db = self.get_database("db", autocommit=1)
        cx = db.cursor()
        cx.execute("select 'hello' as msg")
        res = cx.dictfetchone()
        self.log.info("message is %(msg)s", res)

if __name__ == "__main__":
    script = Hello(sys.argv[1:])
    script.start()

"%(msg)s"って何って方は

404 Not Found

あたりを見てください。別にself.log.info("message is %s", res['msg'])でもいいんだけど。

実行結果

2008-05-12 22:13:41,268 75177 INFO message is hello
2008-05-12 22:13:42,270 75177 INFO message is hello
2008-05-12 22:13:43,272 75177 INFO message is hello
...

起動時の引数で--verboseが指定されていれば、DEBUG以上のログが出力され、--quietであればWARNNING以上のログのみが出力されます。どちらも指定されていなければ、INFO以上のログのみが出力されます。

ログをファイルに出力する

先程の例ではログをstderrに出力していました(logging.handlers.StreamHandlerが使われていた)。

ログをファイルに出力する場合は、設定ファイルでlog_fileを指定します(logging.handlers.RotatingFileHandlerが使われます)。またログのローテーションをlog_size、log_countで設定します。

skylogを使う

もっと色んなログの設定をしたい場合は、設定ファイルでuse_skylog=1としてskylogを使います。skylogを使うと、Pythonの他のLoggingHandler(例えばsyslogを使ったりログをメールで送ったり)を使うことや、ログのフォーマットを詳細に指定することができます。

skylogは、設定ファイルをカレントディレクトリのskylog.ini、~/.skylog.ini、/etc/skylog.iniの順で探し、最初に見つけたファイルを読み込みます。

設定ファイルはPythonのlogging.config.fileConfig()そのものなので、そっちを見てねという感じなのです

skylogの独自のHandlerとして

  • EasyRotatingFileHandler(ほとんどRotatingFileHandlerと一緒だけどパスの指定に"~"を使うことができる)
  • UdpLogServerHandler(JSON形式でUDPで送信する。何に使うんだ?)
  • LogDBHandler(ログをDBに保存する。けどlog.add()という関数は自分で作らなきゃいけないのだろうか)

というハンドラクラスを使うことができるみたいです。

あとソースツリーのpython/conf/skylog.iniに設定ファイルのサンプルがあります。駆け足になりましたが力尽きたのでこの辺で。

*1:06/03追記:修正されたバージョン2.1.7がリリースされました

LarkLark2012/01/12 03:40Percfet shot! Thanks for your post!

vyrugouvyrugou2012/01/12 18:07WqdaHu <a href="http://bikcuisoadpz.com/">bikcuisoadpz</a>

mgkcabbquvxmgkcabbquvx2012/01/13 23:30ET5tQD , [url=http://oisjuydxiaem.com/]oisjuydxiaem[/url], [link=http://okvxreacafxh.com/]okvxreacafxh[/link], http://yggbtzibtmma.com/

htoxjqbvmzhtoxjqbvmz2012/01/14 20:56Olo51I <a href="http://wiqeutrwdgcf.com/">wiqeutrwdgcf</a>

tcreketcreke2012/01/16 20:33QVaXyc , [url=http://mbbmjjjnoxlu.com/]mbbmjjjnoxlu[/url], [link=http://mnpppqwdumdl.com/]mnpppqwdumdl[/link], http://jdoqylxyapyb.com/

トラックバック - http://postgresql.g.hatena.ne.jp/iakio/20080513