似非プログラマのうんちく

「似非プログラマの覚え書き」出張版

巳年じゃないけど Python やろうぜ(その 13)

ロギングの話

デフォルトでもある程度のログは出力されるのですが、データベースとの連携においては、少なくとも開発の段階では SQL の発行状況などを確認したいと思うはずです。これは settings.py に設定を記述することで可能になります。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}

最初の二つの設定は、ほぼこれで固定と思って間違いありません。'version': 1 は dictConfig のフォーマットの現時点で唯一のバージョンを指定するもので、'disable_existing_loggers': False は、既にある Logger を無効化しない設定です。デフォルトで True になっているので、書かないと既存の Logger が全て無効化されてしまいます。

それ以降は個別の用途に合わせて自由に書ける項目です。handlers はログの出力先で、用途に応じてファイルへの保存や管理者宛のメールなども設定できます。今回はコンソールへの出力を設定しています。level は最も強い(= デバッグ用の低レベルなシステム情報も出力する) DEBUG に設定しています。loggers で、データベース関連のバックエンドに関して DEBUG レベルでコンソールにログを出力させる設定をしています。これによりデータベースに対して発行される SQL をコンソールで見られるようになります。

待たせたな ! 動かしてみるぞ !

$ ./manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
(0.013) 
            SELECT name, type FROM sqlite_master
            WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
            ORDER BY name; args=None
(0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
February 16, 2017 - 17:32:11
Django version 1.10.5, using settings 'django_test.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

早速 SQL が発行されてますね。

画面が出ました。試しに ID に整数値しか入れられないことを確認するために、わざと小数を入れてみます。

そこにメッセージ出るかー、って感じです*1が、ちゃんとチェックはされてます。

正の整数以外は弾いてくれるでしょうか。

ウィッス。ちゃんと怒ってくれました。

実際のデータに対応する ID を入れたら、ちゃんとデータが表示されました。

(0.001) SELECT "customer_search_customer"."id", "customer_search_customer"."name", "customer_search_customer"."phone" FROM "customer_search_customer" WHERE "customer_search_customer"."id" = 3; args=(3,)

コンソールにはこのとき発行された SQL が表示されています。では、実際には存在しない ID = 6 を入れたら…?


(0.001) SELECT "customer_search_customer"."id", "customer_search_customer"."name", "customer_search_customer"."phone" FROM "customer_search_customer" WHERE "customer_search_customer"."id" = 6; args=(6,)
Not Found: /customer_search/

SQL を発行して検索を掛けたけどデータはないので、期待通り 404 Not found になりました。

このアプリの問題点

今回作った検索アプリですが、いろいろ問題点が。

  • そもそも ID を入力して検索すること自体が不自然な設計。普通は顧客名を入力して連絡先を取得するか、連絡先を入力して顧客名を取得するのが自然だろう。
  • 常にページ遷移が発生している。

他にもあるかもしれませんが、二つ目のページ遷移問題については、いずれ「Ajax を導入する」ことで解決する手法は紹介しておきたいな、と思います。

Ruby on Rails v.s. Django

シリーズはまだ続きますが、某 SNS にて「RoR を使ったことのある立場から見て Django はどうですか ?」と聞かれたので、ここでまとめておこうと思います。あくまでも私個人の感覚で、正直どちらも割と中途半端にしか使ってないので、参考にはならないかもしれませんが。

まず両者に共通するのは「実際にコードを書く量は少ない」という点かと思います。設計思想に少し違いがあって、Rails は「必要なコードのテンプレはコマンド入れれば作ってあげるよ。」、Django は「こういう書き方、結構するでしょ ? それ僕らがショートカットとか作っておいたから使って。」といったところでしょうか。作られたテンプレにアレンジを加えていくか、あらかじめ用意されたものを必要に応じて組み合わせるか。

あと、「らしい書き方ができる」のも魅力に感じます。Rails なら Ruby らしく、Django なら Python らしく書ける。当たり前のようですが、Struts 経験がある自分にはこの点は大きいです。やったことある人はわかると思いますが、Struts って設定用の XML とかゴロゴロ出て来て実はあまり Java らしくないし、そもそも XML のテストって自動化できない。いや、自分が知らないだけでできるのかもしれないけど、仕事でもそんなのやらされたことない(笑)。だからって Struts がアカンかというとそういうわけじゃないと思うけど、単一言語の知識の範囲内で収まることは、学習コストの低下(= 勉強量が少なくて済む)にもつながるし良いと思います。

だから個人的には甲乙付け難いんですよねぇ…。それでも強いて優劣をつけるなら、「言語仕様レベルで『読み易いコード』が書ける」という点で Python + Django を押します。ちなみに「他の人はどうなんだろう」と思って、いくつか比較記事を読んでみましたが、「Rails も頑張ってるけど Django 押し」な人が多いイメージでした。日本語情報の少なさが弱点ですが、そこを英語力でカバーできれば十分な情報が手に入ると思います。さすがは Python、人気度で Perl を上回っただけのことはある。

結論 : 好きな方を選んだらええんやで

*1:メッセージの表示位置を変える方法を知ってる人がいたら、情報提供をお待ちしております。