Heroku の動作変更? Django の DATABASES 設定でコケた

以前 この記事 で書きましたが, Heroku の上で OSQA という Django アプリを動かしました.

最近また Heroku に静的ファイルを追加するため, git レポジトリにファイルを追加し, Heroku に再デプロイ (git push) しました.

これでアプリが再起動され, 無事動くはずだったのですが, Internal Server Error が出てしまいほとほと困りました.

heroku logs で見てみると不可解なことに, 使ってないはずの PostgreSQL に接続しようとしてエラーになっています.

2012-06-10T04:04:13+00:00 app[web.1]: /app/.heroku/venv/lib/python2.7/site-packages/gunicorn/glogging.py TIME: 2012-06-10 13:04:13,215 MSG: glogging.py:exception:143 Error handling request
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 99, in handle_request
2012-06-10T04:04:13+00:00 app[web.1]:     respiter = self.wsgi(environ, resp.start_response)
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 68, in __call__
2012-06-10T04:04:13+00:00 app[web.1]:     return self.application(environ, start_response)
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 250, in __call__
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 45, in load_middleware
2012-06-10T04:04:13+00:00 app[web.1]:     self.load_middleware()
2012-06-10T04:04:13+00:00 app[web.1]:     mod = import_module(mw_module)
2012-06-10T04:04:13+00:00 app[web.1]:     __import__(name)
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/forum/middleware/extended_user.py", line 4, in <module>
2012-06-10T04:04:13+00:00 app[web.1]:     from forum.views.auth import forward_suspended_user
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/forum/views/__init__.py", line 5, in <module>
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/forum/views/meta.py", line 18, in <module>
2012-06-10T04:04:13+00:00 app[web.1]:     import meta
2012-06-10T04:04:13+00:00 app[web.1]:     from forum.badges.base import BadgesMeta
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/forum/badges/__init__.py", line 5, in <module>
2012-06-10T04:04:13+00:00 app[web.1]:     from base import BadgesMeta
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/forum/badges/base.py", line 12, in <module>
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/models/query.py", line 107, in _result_iter
2012-06-10T04:04:13+00:00 app[web.1]:     installed = dict([(b.cls, b) for b in Badge.objects.all()])
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/models/query.py", line 772, in _fill_cache
2012-06-10T04:04:13+00:00 app[web.1]:     self._fill_cache()
2012-06-10T04:04:13+00:00 app[web.1]:     self._result_cache.append(self._iter.next())
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/forum/models/base.py", line 134, in iterator
2012-06-10T04:04:13+00:00 app[web.1]:     key_list = [v[0] for v in self.values_list(*values_list)]
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/models/query.py", line 107, in _result_iter
2012-06-10T04:04:13+00:00 app[web.1]:     self._fill_cache()
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/models/query.py", line 772, in _fill_cache
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/models/query.py", line 959, in iterator
2012-06-10T04:04:13+00:00 app[web.1]:     self._result_cache.append(self._iter.next())
2012-06-10T04:04:13+00:00 app[web.1]:     for row in self.query.get_compiler(self.db).results_iter():
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 680, in results_iter
2012-06-10T04:04:13+00:00 app[web.1]:     for rows in self.execute_sql(MULTI):
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 734, in execute_sql
2012-06-10T04:04:13+00:00 app[web.1]:     cursor = self.connection.cursor()
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/backends/__init__.py", line 252, in cursor
2012-06-10T04:04:13+00:00 app[web.1]:     cursor = util.CursorWrapper(self._cursor(), self)
2012-06-10T04:04:13+00:00 app[web.1]:     raise ImproperlyConfigured("You need to specify NAME in your Django settings file.")
2012-06-10T04:04:13+00:00 app[web.1]:   File "/app/.heroku/venv/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 125, in _cursor
2012-06-10T04:04:13+00:00 app[web.1]: ImproperlyConfigured: You need to specify NAME in your Django settings file.

う〜ん, ClearDB という Add-on で MySQL を使ってたはずなのですが, これは困りました.

ひとまず heroku run python でインタプリタに入って, 設定ファイルがどう読まれてるか見てみました.

>>> import settings_local
>>> settings_local.DATABASES
ちゃんと設定されてる
>>> import settings
>>> settings.DATABASES
あれ? PostgreSQL になってる??

どうやらここに原因がありそうです.

しかし, DATABASES に関しては settings.py 内で from settings_local import * としてるだけなので, 設定が変わることないはず……

もしやと思い settings.py の中身を heroku run cat settings.py で見てみると

# ここまでは手元と同じ内容

import dj_database_url

if 'DATABASES' not in locals():
    DATABASES = {}

if not 'default' in DATABASES:
    DATABASES['default'] = {}

DATABASES['default'].update(dj_database_url.config(default='postgres://'))

ぬぬぬ, 末尾に何か設定が追加されています. しかもこれだと問答無用で DATABASES['default'] が上書きされてしまいます……

改めて git push heroku master としたときの画面に出るログを見てみると

-----> Injecting Django settings...
       Injecting code into ./settings.py to read from DATABASE_URL
 !     Notice: settings injection will be deprecated for all new Django
 !     apps on July 1, 2012. Learn more:
 !     https://devcenter.heroku.com/articles/django-injection

というのがありますね…… いつの間にか injection されてたのか……

今のとこ未解決ですが, とりあえず現状を書いておきます.

追記: 解決

世界を股にかける Hadooper @shiumachi が調査してくれて, https://devcenter.heroku.com/articles/django-injection というページを教えてもらいました. very thx! やっぱりどうやら勝手に settings.py の末尾にデータベース設定を追加しているようです. Reasoning のとこにごちゃごちゃ書いていますが, これははたして PEP 20 にあるような Pythonic な選択なのでしょうか? 甚だ疑問です.

それはさておき https://devcenter.heroku.com/articles/django-injection#try_it_out_today にあるように .heroku/injection_disabled というファイルを作成して git push したら無事動きました. ロゴの変更も無事済みました.

なかなか黒ミサっぽい感じですね → http://glowing-moon-7493.herokuapp.com/

それでは.

Comments

blog comments powered by Disqus

Licenses