(ここで書いた内容はいけてなくてこっちで更新してます)
今VoltDBというインメモリ型DBに携わってます。
DB操作のスクリプトを組むときにやっていることを書きます。
VoltDBというのはクセのある子(と感じてる)で、他のDBとくらべて少し違うことに気をつけておくことがあります。
DBとしての操作をするには(selectでもdeleteでも)基本的にProcedureというあらかじめの処理手順の登録が必要です。
状況とか任意のテーブルのレコード数のアドリブでの確認にコマンドラインとしてsqlcmdというのが用意されてます。*1
他のDBでdbiインタフェースを使ってスクリプト言語でさくさくというのがなかなかできにくいと感じていて、よく、たとえばmysqlとかでもpythonでMySQLだいたいどのDBでもコード手順は似たものになりますけども、VoltDBの場合には、基本Procedureベースで操作することになります。pythonインタフェースも用意されてますけどプロシージャを指定して起動する、といった
VoltDBにはJsonインタフェースがあるので従来のDBIを使わずともpycurl+jsonあたりでDB操作ができるのだけれども、それも如何せんまずProcedureを準備しないといけなくて、スクリプトのメリットである一面・アドリブ的な使い方ができずにいました。
sqlcmdというコマンドはコマンドラインからqueryを受け付けてくれるのでそれを利用して、一時的にcreate procedureを作って、やりたい操作をして、最後procedureを消しておくというようなスクリプトを組むようになりました。
pythonインタフェースはvoltdbclientになっていて、以下の例だとそれを使っています。
一時procedureを作成するのにsqlcmdコマンドをsubproessで起動し、sqlcmdの--queryオプションでcreate/drop procedureを渡してます。*2
プロシージャ呼び出しはこの例はvoltdbclientを使ってますが、pycurlなりでhttpインタフェースも使えますし、そちらのほうが書く量が少ないかもしれません。*3
とにかく特にアドリブ的にVoltDBにアクセスしたいときに、同じスクリプトでプロシージャの中身を自由に編集しながら、その結果を加工処理するのをなるべくコンパクトに書きたかったのが動機です。
#!usr/bin/env python # -*- coding:utf-8 -*- import ipaddr import os.path import subprocess import sys import time import traceback from voltdbclient import * SQLCMD="/opt/voltdb/bin/sqlcmd" #OPTION="--output-format=csv" QUERY="--query=%s" def execsqlcmd(sql): result = subprocess.check_output([ SQLCMD, QUERY % sql ], shell=False) lines = result.split(b'\n') tuples=[] begin=False for l in lines: if not begin: if l.startswith(b'-') : begin = True continue else: if len(l)==0: break tuples.append([x.decode('utf-8') for x in l.strip().split()]) return tuples NAMETEMPLATE="tempproc" tempprocs=[ ("select * from sample where column=?",[FastSerializer.VOLTTYPE_INTEGER]), ] def init(): # check sqlcmd if not os.path.exists(SQLCMD): print SQLCMD,"doesnt exist." sys.exit(1) # create procedures temporary for idx,s in enumerate(tempprocs): command = "create procedure %s%d as %s" % (NAMETEMPLATE, idx, s[0]) execsqlcmd(command) print command def close(): for idx,s in enumerate(tempprocs): command = "drop procedure %s%d" % (NAMETEMPLATE, idx) execsqlcmd(command) print command def mainloop(client): proc = VoltProcedure( client, NAMETEMPLATE+"0", tempprocs[0][1]) response = proc.call( [ 0 ] ) return response try: init() client = FastSerializer("localhost", 21212) response = mainloop(client) print response.tables except: traceback.print_exc() pass finally: close() # end of file