[TurboGears] @paginateデコレータで並び順を指定する場合は、SQLAlchemyが必要である(たとえモデルにSQLObjectを使っていても)。
環境
この記事の内容は、TurboGears 1.0.1で確認しました。
現象
以下のような、default_order引数を含む@paginateデコレータをメソッドに付加します。
@paginate(var_name="authors", max_pages=car.const.list_max_page, limit=car.const.list_limit, default_order="name")
すると、以下のような例外が発生します。
500 Internal error
The server encountered an unexpected condition which prevented it from fulfillin
g the request.
Page handler: >
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/CherryPy-2.2.1-py2.4.egg/cherrypy/_cpht
tptools.py", line 105, in _run
self.main()
File "/usr/lib/python2.4/site-packages/CherryPy-2.2.1-py2.4.egg/cherrypy/_cpht
tptools.py", line 254, in main
body = page_handler(*virtual_path, **self.params)
File "", line 3, in index
File "/usr/lib/python2.4/site-packages/TurboGears-1.0.1-py2.4.egg/turbogears/c
ontrollers.py", line 334, in expose
output = database.run_with_transaction(
File "", line 5, in run_with_transaction
File "/usr/lib/python2.4/site-packages/TurboGears-1.0.1-py2.4.egg/turbogears/database.py", line 302, in so_rwt
retval = func(*args, **kw)
File "", line 5, in _expose
File "/usr/lib/python2.4/site-packages/TurboGears-1.0.1-py2.4.egg/turbogears/controllers.py", line 351, in
mapping, fragment, args, kw)))
File "/usr/lib/python2.4/site-packages/TurboGears-1.0.1-py2.4.egg/turbogears/controllers.py", line 378, in _execute_func
output = errorhandling.try_call(func, *args, **kw)
File "/usr/lib/python2.4/site-packages/TurboGears-1.0.1-py2.4.egg/turbogears/errorhandling.py", line 73, in try_call
return func(self, *args, **kw)
File "", line 3, in index
File "/usr/lib/python2.4/site-packages/TurboGears-1.0.1-py2.4.egg/turbogears/paginate.py", line 75, in decorated
order_by_expr = sql_order_col(col, order_opts[1])
File "/usr/lib/python2.4/site-packages/TurboGears-1.0.1-py2.4.egg/turbogears/paginate.py", line 249, in sql_order_col
if isinstance(col, sqlalchemy.schema.Column):
NameError: global name 'sqlalchemy' is not defined
対策
以下のようにして、SQLAlchemyをインストールします。
$ sudo easy_install sqlalchemy Searching for sqlalchemy Reading http://www.python.org/pypi/sqlalchemy/ Couldn't find index page for 'sqlalchemy' (maybe misspelled?) Scanning index of all packages (this may take a while) Reading http://www.python.org/pypi/ Reading http://www.python.org/pypi/SQLAlchemy/0.3.5 Reading http://www.sqlalchemy.org Best match: SQLAlchemy 0.3.5 Downloading http://cheeseshop.python.org/packages/source/S/SQLAlchemy/SQLAlchemy-0.3.5.tar.gz#md5=5d4a317c542247f82d1ed7e256976117 Processing SQLAlchemy-0.3.5.tar.gz Running SQLAlchemy-0.3.5/setup.py -q bdist_egg --dist-dir /tmp/easy_install-V_VxP8/SQLAlchemy-0.3.5/egg-dist-tmp-aRiBOE zip_safe flag not set; analyzing archive contents... Adding SQLAlchemy 0.3.5 to easy-install.pth file Installed /usr/lib/python2.4/site-packages/SQLAlchemy-0.3.5-py2.4.egg Processing dependencies for sqlalchemy
詳細
エラーは、/usr/lib/python2.4/site-package/TurboGears-1.0.1-py2.4-egg/turbogears/paginate.pyの以下の箇所で発生しています。
def sql_order_col(col, ascending=True): """Return an ordered col for col.""" if isinstance(col, sqlalchemy.schema.Column): if ascending: order_col = sqlalchemy.sql.asc(col) else: order_col = sqlalchemy.sql.desc(col) elif isinstance(col, types.InstanceType): # I don't like using InstanceType, but that's what sqlobject col type # is. if ascending: order_col = col else: order_col = sqlobject.DESC(col) else: raise StandardError, 'expected Column, but got %s' % str(type(col)) return order_col
ここでsqlalchemyモジュールを参照していることが問題です。ファイルの冒頭で、SQLAlchemyがない場合の対処をしているのですが、
try: # Can't depend on sqlalchemy being available. import sqlalchemy from sqlalchemy.ext.selectresults import SelectResults as SASelectResults except ImportError: SASelectResults = None
実際にはコードの中で使われてしまっているので、この対応方法は中途半端です。
よって、モデルにSQLObjectを使っていても、@paginateデコレータで並び順を指定する場合は、SQLAlchemyが必要です。
所感
んなアホな...。