2012/12/16

自分のための「PythonでDBの自動構築」

とりあえず、Python 経由でPostgreSQL + PostGIS 2.0の環境を構築するスクリプト。
ついでに、UDFを内部で定義できるように、PL/Python の設定も行なっている。
結論から書くと、必要なコードは以下の通り。

何に必要かというと…秘密…では無いのだが、説明が面倒。興味ある人は、個別に。
要するに、私の研究の都合上、必要なので、メモも兼ねて書いておくにする。
役に立ちそうなことと言えば、subprocess.call の使い方くらい。何でも有りの裏技。

#!/usr/bin/python
# -*- coding: utf-8

import subprocess

# Create a new database
dbname = "sampledb"
subprocess.call("createdb %s -T template_postgis" % (dbname), shell=True)
subprocess.call("createlang plpythonu %s" % (dbname), shell=True)

ここでは、PostGIS 2.0 のテンプレートを適用している。
この部分は、事前に設定していないとダメ。その設定方法は以下の通り。
以下はBashによる設定。Ubuntu 12.04では正常に動作。

# Create a new database for the template.
createdb -E UTF8 template_postgis
createlang -d template_postgis plpgsql
# Create the template by using PostGIS sql files.
psql -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis'" -d postgres
# Apply spatial extension to the database.
psql -f /usr/share/postgresql/9.1/contrib/postgis-2.0/postgis.sql -d template_postgis 
# Insert information of spatial reference system to the database.
psql -f '/usr/share/postgresql/9.1/contrib/postgis-2.0/spatial_ref_sys.sql' -d template_postgis
# Apply PostGIS raster extension to the database.
psql -f '/usr/share/postgresql/9.1/contrib/postgis-2.0/rtpostgis.sql' -d template_postgis

psql -c "GRANT ALL ON geometry_columns TO PUBLIC;" -d template_postgis
psql -c "GRANT ALL ON geography_columns TO PUBLIC;" -d template_postgis
psql -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;" -d template_postgis

折角の機会なので、ついでに、簡単なUDFを書いてみる。
やはり、最初に書くなら「Helloworld」。とにかく、これが動けば第一段階クリア。
あれだけ苦労したのに、見直してみると、僅か数行のこと。最初はそんなもの。

さて、今回は、ちょっとインチキして、pgAdminIII のインタフェースからログイン。
そんでもって、SQLエディタで書いてみる。書き方は、それほど難しくなさそう。
以下は、単に、「Hello World」という文字列を返すだけの関数

CREATE FUNCTION return_helloworld() RETURNS character AS
$$
return ("Hello World")
$$ LANGUAGE plpythonu;

まず、CREATE FUNCTION の後ろに関数名を書いて、RETURNSの後ろに返り値の型。
$$」と「$$ LANGUAGE plpythonu」の間にPython コードを書くだけ
とりあえず、一行だけのコード。この実行結果のスクリーンショットは以下の通り。


ちゃんと、コードは通っている模様。上段に、先程のコードが書いてある。
SELECT return_helloworld();定義した関数を実行
画面下段に実行結果が出力されている。

なお、CREATE FUNCTION関数は、自動的には上書きしてくれないので、
同じ関数名のUDFを作ろうとすると、以下のようなエラーが帰ってきてしまう。
これは少々面倒…かと思ったら、実は、大したことは無かった

ERROR:  function "return_helloworld" already exists with same argument types

********** Error **********

ERROR: function "return_helloworld" already exists with same argument types
SQL state: 42723

作成した関数を修正したい場合には、以下のように、一度、関数を削除し、
もう一度、作り直せば良いらしい。次の例では、既存の関数を削除した後、
先程のコードを修正し、変数「value」に値を入れてから結果を返すようにしている。


DROP FUNCTION return_helloworld();

CREATE FUNCTION return_helloworld() RETURNS character AS
$$
value = "Hello World 2"
return (value)
$$ LANGUAGE plpythonu;

大体、状況は飲み込めてきた。では、作成したUDFはどこに保存されるのか?
pgAdminIIIのインタフェースで見てみると、以下のようになっている。


Public スキーマの中の「Function」という所に自動的に保存されているらしい。
先程、自分で定義した「return_helloworld()」が無事に定義されている。
ログインユーザに色々と不備があるが…まぁ、今は関係ないから良いことにする。

さてさて、最初の段階はどうやらクリアできたらしい。
PL/Python、 今日、初めて試した。まだよくわかっていない。
もう少し、試してみて、理解が進んだらこの記事も書き直そう…

0 件のコメント:

コメントを投稿