DBについて

DjangoはDB(テーブル)を設計できれば、割と簡単にWebアプリが作れます。裏を返せばテーブル設計できないとダメです。
Djangoに関するDB関連のことと、一般的なテーブル設計についてです。

DBMS

正式にサポートしているDBMS

使うDBMSによって注意点があるので Databases | Django documentation | Django を参照。
上記以外のDBMSサードパーティーのドライバ Databases | Django documentation | Django があります。
また、NoSQLを使いたい方向けのプロジェクト Django non-rel もありますが、この記事ではRDBのことだけ考えます。

テーブルの論理設計(データモデリング

DBMSをインストールしたり、DB作成したり、DBMSによってやり方があります。たくさん情報があるのでググって下さい。
クラウドでDBのPaaSを使うと「これでDB作れたのか?」「勝手にスケールできちゃう!」「勝手にインデックス張ってくれる?!」になってます。今のところテーブルの論理設計はエンジニアがやらないとできないので、まとめておきます。
(mBaaSやら、自然言語からSQLを作るサービスもあるので、そのうちテーブル設計もエンジニアがやらなくなりそうですが…)

テーブル設計について一通り盛り込まれていて、簡潔にまとまってる記事を見つけたので拝借。 DB論理設計のノウハウ - Qiita
この記事の内容で気になる点がいくつかあったのでメモしておきます。

自然キーを使うべき?

業務が変わるとキーが変わる可能性もある(殆どないですが…)ので代理キーを使うべき。の考え方もあり、私は代理キー派です。またDjangoを普通に使うと代理キーです。

正規化は第三正規形まででOK?

非正規化すると検索し易くなり(その検索処理だけコードが簡単になったり、レスポンスが良くなったり)ます。逆に、正規化するほど業務の実態に近づきます。業務の実態に近いということは、仕様が変わってもテーブルの変更も対応し易い(正しくテーブル設計できていれば、テーブルには手が入らない。または、変更はなくテーブルの追加だけで対応できます。)です。非正規化した項目は、画面の仕様が変わると、全く役に立たないゴミデータになる可能性があります。後々のことを考えると、できるだけ正規化しておきたいです。

物理設計の内容

クラウドサービスを使うとあまり意識しなくて良くなってきてます。もちろん理解しておいた方が良いですが、優先度を下げて考えても良いのかと思います。

上記の記事でテーブル設計について一通りまとまっていますが、難しい単語があって頭に入りにくい部分もあります。
なので、もう少し分かり易い記事。 4ステップで作成する、DB論理設計の手順とチェックポイントまとめ - Qiita
この記事も気になる点をメモ。

主キーをidにするとSQLでjoinした際に混乱するからentity名_idとするべき?

Djangoでは主キーを定義しないと、自動的にidという主キーを作ってくれます。DjangoのORMだけ使用する場合、この記事の指摘は気にしなくて大丈夫ですが、Djangoでも生SQLを書くことができます。その場合はこの記事のとおり モデル名_id にしておいた方が無難でしょう。

中間テーブルについて

中間テーブルが「多:多の関係を解消するために、業務要件にないけど人工的につくるテーブル」として説明されています。確かに多:多を解消しますが、業務分析が不充分であるとも言えます。
この記事の例で言うと、学生は新学期が始まる際に新しい講義を選択し、受講期間を申し込むイベントがあるはずです。例にある中間テーブルに日付(受講期間)を追加したものが、このイベントのテーブルとして定義されるべきです。

上記の中間テーブルをイベントのエンティティに落とし込む点に重点をおき、分かり易く業務分析/データモデリング(≒論理設計)する手順を説明したスライドを見つけました。
イミュータブルデータモデル(入門編)
このスライドを作成した方のベースにはT字型ERがあるようです。
www.amazon.co.jp
私も以前この本を読みました。言葉が難しいですが、テーブル設計が楽に出来るようになります。余裕があれば読んでみてください。

テーブル設計におけるDjangoの制約

複合キーは使えない

使いたい場合は、サロゲートキー + 複合ユニークキーにする。
日々の記録 : django で複合ユニーク制約をつける方法

ORMでテーブルを結合検索したい場合、modelのFieldにForeignKeyの指定が必要

ForeignKeyを張ると面倒な場面があるので、以前は物理設計時にForeignKey制約を外したこともありましたが、外さない方が良いです。ForeignKey制約についてちゃんと考えてる記事 キーレスエントリ(外部キー嫌い) - Ynishi Bussiness Logs があったので参考にしてみて下さい。
ちなみに、 Djangoでも modelのField定義で db_constraint=False を指定することで、ForeignKey制約なしにするのは可能ではあります。

customer = models.ForeignKey('Customer', null=True, blank=True, db_constraint=False) 

テーブル設計用のツール

A5:SQL Mk-2 - フリーの汎用SQL開発ツール/ER図ツール .. 松原正和

本当に便利。10年ぐらいこれしか使ってないので、他のおすすめが分からない。
できること/特徴。

  • ER図を作成
  • ERからテーブル定義書作成
  • ERからテーブル作成
  • テーブル定義書からテーブル作成
  • 上記の逆(リバース)
  • SQL実行
  • 取得したデータをExcelっぽく表示
  • Excelにコピペ
  • ExcelのデータをコピペしてDBに登録
  • CSVに出力
  • CSVで入力
  • 主要なRDBMSにだいたい対応
  • ダミーデータ自動作成
  • 無償

きっと他にも良いところがあるはず。

Djangoについて

Pythonで作られたフルスタック・フレームワークフルスタック・フレームワークを使ったことがない方は、Djangoに限らずですが一度使ってみて下さい。便利でビビリます。

以下、Djangoの特徴について。

MVC(MTV)

 いわゆるMVCフレームワークですが、Djangoでは以下のような対応になっていて紛らわしい。

通常のMVC Djangoの場合
M models
V templates
C views

 モデルとテーブルの同期

 先述の models からDBのテーブル(データじゃない)を作成・変更・削除したり、逆に既存のテーブルからmodelsを作成したりできます。(失敗してハマることはありますが…)

Adminサイト

DBとテーブルを作ればテーブルのデータをメンテナンスできる管理画面を、ほとんど自動的に作成でき、カスタマイズもできます。

用途は、マスタメンテ画面として使用したり、プロトタイプとしても使えると思います。カスタマイズを上手くできるようになれば、簡単にプロトタイプをつくれるようになりそうです。

認証機能がついてる

Django でのユーザ認証 — Django 1.4 documentation にある通り、はじめから認証機能があります。固有アプリ用の画面(template)に変えるだけで充分使えます。

また、Djangoシングルサインオンできる外部PKGもあります。

URLディスパッチャの正規表現

通常のMVCフレームワークルーター(クライアントからのリクエストを最初に振り分けるとこ)がURLディスパッチャ(urls.py)と言う名前なのですが、リクエストURLが正規表現にマッチしたら振り分ける仕組みになってます。ここ以外は直観的に作れる感じなのですが、正規表現をスラスラかける人なんているのかしら?と思ってしまいます。

Djangoの設計思想

他にもたくさん特徴があるのですが、Django の設計思想 — Django 1.4 documentation を説明した記事があります。聞いたことない単語が出てくるし、直訳っぽいので読みにくいですが、考えこまずにひとまず読んでみてください。その後、この設計思想について書いた記事、Java開発者の読むDjangoの設計思想 - やさしいデスマーチ を読むと、自分がJavaをやっていたせいもあるかもしれませんが、とても理解し易いです。

Djangoの特徴を自分でちゃんと書こうと考えてましたが、Java開発者の読むDjangoの設計思想 - やさしいデスマーチ が解り易いので、これでおしまい。

 

Pythonについて

Pythonのことは検索すれば色々あるので気が済むまで調べていただきたいですが、私が感じてる特徴をザックリ書くとこんな感じ。

  1. いわゆるスクリプト言語
  2. 動的データ型
  3. ブロックをインデントで表現(カッコを使わない)ので見た目スッキリ
  4. なんか書き易い(見易い?3.のおかげか?)
  5. 標準ライブラリ&サードパーティーモジュール(パッケージ)が豊富

しっかりお勉強しなくても、ネットで検索すればある程度動くものは作れます。真面目に勉強しようかと思い、

Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目

 

これを読みかけてます。読むと、心なしか自分のコードがカッコ良くなった気がします。

個人的には、5.が一番気に入っていて、いわゆる車輪の再発名をしなくて良いです。「Pythonはデータ分析や、機械学習に向いている。」と言われていますが、多分5.のおかげが大きいのではないでしょうか。

Python(特に5.)の特徴を生かすために気を付けておいた方が良い点、その他の注意点を書きます。

 

英語

Pythonの情報は英語の記事の方が圧倒的に豊富です。日本ではRubyが人気でPythonを使う人が少なかったからだと思いますが、日本語の記事だけ見てPythonのことを調べても、結局英語の記事を読む羽目になります。

また、Pythonサードパーティモジュールを使用する場合は、パッケージ管理サイト PyPI - the Python Package Index : Python Package Index を読むことになります。Pythonだけではないですが、Pythonの場合は特に英語に慣れるべきです。

と書きつつ、私は英語が苦手なので、Google 翻訳 - Chrome ウェブストア これを使ってます。相変わらず英語はダメですが、機械翻訳した日本語に慣れてきました。そのせいか、先述したオライリーの直訳っぽい日本語もスラスラ読めます。

 

パッケージ管理

豊富なサードパーティーモジュール(パッケージ)群を管理するために、pipというものを使います。他にも色々あるみたいですが、まずはpipです。

pipの使い方とインストール - Python入門から応用までの学習サイト で分かり易く説明してくれてます。こちらのサイトは、pipだけでなくPython全般のことを初心者(かつWindowsユーザー)にとても親切に説明してくれてます。ありがたいです。

まずは "pip install -r requirements.txt" は使えるようにしましょう。もう少し凝りたい方は、Python アプリ依存パッケージ管理 ベストプラクティス集 - Qiita など参考にされると良いでしょう。

 

仮想環境

Pythonを始めた頃、勉強に使った色々なサイトに「仮想環境を作成しよう」と当然のように書いてあって「なんで?」と思いました。これも「パッケージを使い分けるのに便利だから」だと思います。

仮想環境を使用すると、PythonインストールディレクトリとPythonパッケージディレクトリを簡単に作成/切り替えできます。開発するアプリ毎に使用するPython(のバージョン)とパッケージをそれぞれ管理できるのです。

例えば、

アプリAでは、Python2.7でDjango1.11を使用したい。

アプリBでは、Python3.6でbottle0.12を使用したい。

場合でも、アプリAはPython2.7の仮想環境を参照し、アプリBはPython3.6の仮想環境を参照することが簡単にできるようになります。

ということで、仮想環境を使った方が便利です。仮想環境の作成/切り替えは、

Python/Djangoの開発環境構築 の際にcondaを使ってやってます。

もっと知りたい方は、

Pythonの仮想環境構築(2017年版) pyenvとpyenv-virtualenvとvirtualenvとvirtualenvwrapperとpyvenvとvenv - Qiita 

など参考にしてはいかがでしょうか?

 

 規約

当然ですが従わなくても動きます。が、新しいプログラム言語を始める際は、その言語の規約には目を通しておくべき。Javaの規約で書かれたPythonプラグラムを見たことがありますが、とても見にくかった…。

Pythonの規約は PEP8(日本語) です。

規約を守ってるかをチェックしたり、自動的に修正するツールもあります。

Python のコーディング規約 PEP8 に準拠する - Qiita

Eclipse+PyDevでPythonコーディング規約(PEP8)を準拠するための環境構築 - Qiita

使ってなかったので参考にしよう。

 

日本語(データ)の扱い

日本語データの取り扱いでハマることが何度かありました。3系では問題ないようですが、私がちゃんと使ったのは2系なのでその際の注意点を

特にハマったのはデータの文字コード変換です。機種依存文字、氏名でたまに使われる難しい方の漢字とかは標準モジュールでは変換できません。pykf 0.4 という拡張パッケージで変換できるのですが、これを発見するのとWindowsへのインストールに苦労しました。

この辺とか参考にしたような…

機種依存文字対策でpykfをインストールしてみた – BTY備忘録

それでもエラーが出て、これもインストールしたような…

Download Microsoft Visual C++ Compiler for Python 2.7 from Official Microsoft Download Center

人って嫌な記憶はなかったことになる仕組みになってるらしいので記憶があやふやで…。

 

Python Django の開発環境構築

まずはPython環境

Pythonの環境を初めて作ろうとググったら、2.x系 or 3.x系とか、仮想環境が○○とか、Pythonコミュニティ標準かAnacondaかとか…、いきなり迷う方もいると思います。

とにかく手軽に環境を作ってみて、解ってきたら後で最適な形に変更することにしましょう。まずはAnacondaを使うことをお勧めします。なぜAnacondaが便利か?とかは一旦置いといてインストールしましょう。

Anacondaのインストールと概要説明は、

Anaconda で Python 環境をインストールする - Qiita

が分かり易く、OSも3パターン(win/mac/Linux)対応で親切、コメントで「なぜAnacondaが便利か?」にも触れてる方がいて至れり尽くせりです。

私も参考にさせていただきました。

 

次はDjangoをインストール

となるところですが、上のPython環境の記事を最後まで読んだ方は、既にDjangoをインストールしています。読み飛ばした人は、もう一度最後まで読みましょう。

はい、Python/Djangoの環境が出来ました。

 

IDE / エディタ

結局は、使い慣れたのを使うのが一番効率が良いと思います。

が、感じたことを書いておくと、開発PCのスペックがそれなりならIDEが良いです。Pythonの特徴の一つに豊富なライブラリ群があり、これらを積極的に使用することで生産性が上がりますが、サードパーティライブラリには最低限の説明しかないものが多々あります。Python使ってるんだからソース読んでね。が常識なのかソースを読まないと使えない場合があります。

そんな時、IDEのデバック機能を使った方が効率的にソースが読めます。最近は、エディタでもデバック機能を拡張できるのがあるので、エディタの場合でも、デバックできるものをお勧めします。

 

お勧めのIDE/エディタ

Eclipse & PyDev

PCスペックまあまあで、OSがWinで、Python以外もやるし、無償だし、使い慣れてて学習コストがかからないいので、私はこれです。

PleiadesでUltimateかPythonを選んでEclipseインストールます。

Pythonはcondaで作った仮想環境を参照するよう設定してます。

PyCharm

Pythonはじめた頃にググったら、みなさんこれを勧めてました。有償だしPython以外に使えるか不明だったので使ってないです。

Visual Studio Code & Python拡張

PCスペックがイマイチの時にこれを使ってました。動作が軽いし、機能も充分で、感心した記憶があります。

 

Python DjangoでWebアプリをつくる

簡単なWebアプリはサクッと作れるようにしておきたい。ための忘備録。

まずは書きたいことを並べてみて、内容を書きながら後々改善する。(予定)

目標記述レベル

何かしらWebアプリ開発経験があって、MVCフレームワークやO/Rマッパーはなんとなく知ってます。でもPython/Djangoやったことありません。ぐらいの人に、「まずはこれ読んどいて。」と言いたい。  

概要

  1. Python Django の開発環境構築 

  2. Pythonについて

  3. Djangoについて

  4. DBについて
  5. Django管理画面について
  6. Python Django以外(クライアントサイド)の構成
  7. 認証
  8. ログ
  9. 一覧検索画面
  10. 更新系画面
  11. ORM
  12. ファイルダウンロード
  13. ファイルアップロード
  14. バッチ

はじめに

システムエンジニアです。

転職をきっかけにコードを書く時間が増えて、エンジニア魂が再燃したのか?

色々記録しておきたいと感じブログを書きます。

内容は、おもにシステム開発の技術的なこと、ときには考えごと、感じたことです。

方針

  • 技術的な内容そのものは技術系のブログに書き、ここは目次のように。
  • 「試してみた」的な内容ではなく、ある程度実用的にしたい。
  • なので、一度書いた内容も改善する。(予定)