cloverrose's blog

Python, Machine learning, Emacs, CI/CD, Webアプリなど

DjangoアプリをHerokuにデプロイしてみた

Djangoで作ったWebアプリをHerokuにデプロイしてみました.
変なところでつまづいてHerokuは難しい><って心が折れかけていましたが,原因はHerokuにも,HerokuのPostgresqlサーバーでもありませんでした.

Heroku 上で Django を動かす - Twisted Mindを読んでやったんだけどうまくいかない><っていう方の役に立つとうれしい.

最初にHerokuにDjangoアプリデプロイできるのかなあとふと思って「Django Heroku」で調べて次の記事を見つけ,これは大丈夫そうだと確信.
Heroku 上で Django を動かす - Twisted Mind

作成済みのアプリに対して上の記事の手順を適用.すべてが順調に進むと思われたが...

$ heroku run python myproj/manage.py syncdb

がうまくいかない.
もともとローカルではSQLiteを使っていたのでmyproj/myproj/settings.pyのDATABASESをいじらないといけない.
しかし,NAME/HOST/PORT/USER/PASSWORDに何を設定していいのかわからない.
USERやPASSはHerokuに登録したメールアドレスとパスワードなのかなって思ったけど違う.

HerokuのドキュメントGetting Started with Django on Heroku | Heroku Dev Centerを読むと,

pip install dj-database-url

をして
requirements.txtを更新して,
myproj/myproj/settings.pyの一番下に

# Parse database configuration from $DATABASE_URL
import dj_database_url
DATABASES['default'] =  dj_database_url.config()

を付け加えればOKって書いてある.これを信じて変更してみるも,うまくいかない.
Printデバッグでdj_database_url.config()の返す値を調べると,

 'ENGINE': 'django.db.backends.dummy', 'HOST': '', 'NAME': ''

これはダメだ.

そんな感じで,何が違うか五里霧中してる時に,Postgresqlの設定画面がWebインターフェースで提供されてることを知ることができた救世主的存在が現れた.
HerokuでPlay2.0+PostgreSQL - argius noteの「PostgreSQL(Heroku Postgres add-on)の設定」の箇所.
https://dashboard.heroku.com/apps/twhy/resourcesのAdd-onsのHeroku Postgres Devをクリック.Connection Settingsの右側の歯車をクリック,Djangoを選択.出力されたDATABASESをmyproj/myproj/settings.pyに貼り付ける.これでOK.
ちなみに,自分はこの設定をするだけで,dj-database-urlは使わずにデプロイが完了した.

Herokuにデプロイするために行った変更をDjangoプロジェクトをHerokuにデプロイする際の変更箇所にまとめた.
この他にもTwitterのコンシューマ情報を保存したconsumer_info.pyをサーバーにPushしなければいけない関係で.gitignoreの変更なども行った.

Heroku Postgres | Heroku Dev Center


ちなみに自分がつまづいていたバグは以下の回答で見事解決.HerokuともPostgresqlとも関係ないDjangoとPythonのpickleに関するものでした.

For the benefit of others who may find this ticket in a search: The error could be due to the fact that pickle.dumps() returned a str, but after restoring the serialized value from the cache it was a unicode object, which pickle.loads() did not expect.
In this case, replacing pickle.loads(c) with pickle.loads(str(c)) may solve the problem.

#10865 (Unable to pickle Queryset) – Django