2008-08-25

SQLObject の __init__ を触ってはいけない

web.py と SQLObject を使ってちまちまやっているわけですが、データベースに行を追加した後、サーバを再起動してから、Foo.select() の戻り値をイテレートしようとすると、応答しなくなりました。リターンしないと言うのでしょうか。エラーが出るわけではないけれど、ずーっと待ってる。



スレッドが分かれているのがいけないのかとか、いろいろ勘ぐったのですが、そんなことではなくて、SQLObject (のサブクラス)の __init__ を触っていたことが原因っぽい。



ちなみにやりたかったことは、各行に順序を表すコラムをつけたかったのです。

class Foo(SQLObject):
    value = StringCOl()
    order_ = IntCol()



    def __init__(self, *args, **kw):
        kw["order_"] = max([0]+[f.order_ for f in Foo.select()]) + 1
        SQLObject.__init__(self, *args, **kw)

ドキュメントには、__init__ に触るな、_init を使え、と書いてありました。ただ、私の今回の目的では、オブジェクトの生成前に order_ コラムを指定したいのですが、_init の引数は _init(self, id, connection=None, selectResults=None) です。connection に Foo インスタンスが入っているっぽい(WingIDE のデバッガが活躍)のですが、ほんとにこれに頼っていいのか分からないのと、どっちにしても Foo をインスタンス化するときに order_ を渡さないといけません。というわけで、こんな風にしました。

class Foo(SQLObject):
    #...



    @classmethod
    def tail(class_):
        return max([0]+[f.order_ for f in Foo.select()])+1

呼び出すときには、

Foo(value="spam", order_=Foo.tail())

です。