2007-12-24

O/R マッパーが、データベース入門の敷居を下げる仮説

みんなの Python Web アプリ編」をちまちま読んでいます。これまでデータベースとかよく分からないよ、と思ってずっと避けてきたのですが、排他制御的なこともやってくれると書いてあったのでちょっと触ってみましたが、やっぱり面倒だなぁと思いつつ読みすすめていって、O/R マッパーの章に突入し、そう言えば TurboGears で使ってる O/R マッパーって何だっけ、と SQLObject を見つけました。わー、すごい。これ分かりやすい。(書籍で紹介されている simplemapper.py は見ただけ)



というわけで、みんPy Webアプリ編 p.123 の dbpole.py を、SQLObject を使って書き直してみました。



ちゃんと SQL も分からん奴が、O/R マッパーなんて使うなと先輩方に言われそうですね。set メソッド発行するたびに UPDATE してるとか、まあいろいろ富豪的に過ぎるところもあります。ですが、こうやって入門の敷居が下がっていくことで、技術というのは使われるようになるのでしょうねぇ、とてきとーなことを言ってみる。



# coding: utf-8

import sqlite3
import sqlobject
from httphandler import Request, Response, get_htmltemplate
import cgitb; cgitb.enable()

form_body = u"""
<form method="POST" action="/cgi-bin/dbpole.py">
  好きな軽量言語は? <br />
  %s
  <input type="submit" />
</form>"""

radio_parts = u"""
<input type="radio" name="language" value="%s" />%s
<div style="border-left: solid %sem red; ">%s</div>"""

class LanguagePole(sqlobject.SQLObject):
    language = sqlobject.StringCol()
    value = sqlobject.IntCol()

def incrementvalue(lang_name):
    item = None
    for item in LanguagePole.select(LanguagePole.q.language == lang_name):
        item.value += 1
    if not item:
        i = LanguagePole(language=lang_name, value=1)

sqlobject.sqlhub.processConnection = sqlobject.connectionForURI("sqlite:/path/to/db")
try:
    LanguagePole.createTable()
except:
    pass

content = ""
req = Request()
if req.form.has_key("language"):
    incrementvalue(req.form["language"].value)
lang_dic = {}

for pole in LanguagePole.select():
    lang_dic[pole.language] = pole.value

for lang in ["Perl", "PHP", "Python", "Ruby"]:
    num = lang_dic.get(lang, 0)
    content += radio_parts % (lang, lang, num, num)

res = Response()
body = form_body % content
res.set_body(get_htmltemplate() % body)
print res