【Django入門】Databaseの使い方

こんにちは!インストラクターの本多です。

皆さんは、Database(データベース)とは何かをご存知ですか?

Databaseは、データを保存するときに欠かせないアプリケーションです。

開発言語やフレームワークとは別に語られることが多いため、いまひとつピンとこないのではないでしょうか?

この記事では、

・Databaseとは
・DjangoでDatabaseを使ってみよう

といった初歩的な内容から、

・PythonインタラクティブシェルでDatabaseへデータを保存する
・PythonインタラクティブシェルでDatabaseに登録したデータを表示する
・開発サーバ(管理画面)でデータをメンテナンスする

などの応用的な内容を解説します。

また、さらに高度な内容として、

・DatabaseをMySQLに切り替える
・Databaseを別のホストにする

といったことも解説します!

それでは、行ってみましょう!

目次

Databaseとは

そもそもDatabaseとは

例えば、ユーザー管理やログイン履歴の保存など、Webアプリケーションでデータを保存するとき、あなたならどうしますか?

テキストファイルにデータを保存しておく、という手がありそうですが、取り扱いや保守性の面で困難が伴います。

このようなときに、PythonやDjangoとは、まったく別のアプリケーションであるDatabaseの出番となります。

WebアプリケーションからDatabaseに指示を出せば、データの保存や呼び出し、更新、削除が簡単にできます。

もっとシンプルに、Databaseを「データの格納庫」と呼んでもよいでしょう。

Databaseの種類

Djangoでは、標準でSQLiteを利用します。

勉強目的では仕組みがシンプルなSQLiteが適していますが、Webアプリケーションの規模が大きい場合は、SQLiteでは力不足になる可能性があります。

実はDatabaseにはいろいろな種類があり、Djangoでは、MySQL、PostgreSQL、Oracleも利用できます。

オープンソースソフトウェア(OSS)で、導入実績が多いDatabaseは、MySQLが有名ですね。

いろいろなDatabaseに興味がある方は、こちらの記事もご覧ください。

リレーショナルデータベースにデータを格納

SQLiteでは、テーブルという、Excelの表形式のようなイメージでデータを格納します。

今回の記事では、以下のようなデータを取り扱うことにします。

BookID書名著者
1Python No.1Python Taro
2Python No.2Python Jiro
3Python No.3Python Saburo

そこでテーブルを、以下のように定義します。

論理名物理名データ型主キー
BookIDbookidINTEGER
(整数)
書名titleVARCHAR(100)
(文字列100バイト)
著者authorVARCHAR(30)
(文字列30バイト)

この表を、テーブルレイアウトと呼びます。

テーブルレイアウトの各項目の意味は、以下のとおりです。

項目説明
論理名項目の日本語名で、多くの人が理解しやすい名前をつけます。
物理名
項目のDatabase内の名前で、開発者が理解しやすい名前をつけます。
データ型
各項目のデータ種別(数値、文字列など)を指定します。
主キー
(プライマリーキー、Primary Key)
テーブルの中で、一意の値(重複がない値。ユニークな値)を設定するデータ項目に○をつけます。
主キーに○をつけた酷木に設定した値(このテーブルレイアウトであればBookIDに設定した値:1、2、3)を指定して、テーブル内の行を選択します。データの背番号とも言えます。

Databaseのデータを取得・更新するときは、主キーの値(1、2、3)を指定して、テーブル内の行を選択し、その他のデータ(書名や著者)を取得・更新します。

Databaseとテーブルの関係

通常、1つのWebアプリケーションで、複数のテーブルを扱います。

そこで、次の図のように、1つのDatabaseに複数のテーブルを作るというデータ構造にします。

データベースとテーブルの関係

WebアプリケーションごとにDatabaseが1つあるというデータ構造です。

DjangoにおけるDatabase

Databaseにデータを格納するためには、Databaseを取り扱うSQLというDatabase独自の言語を使用しなければいけません。

たとえば、本の情報を登録するには、以下のようなSQL文が必要です。

-- Databaseの作成
CREATE DATABASE BOOKS;

-- Databaseの選択
USE BOOKS;

-- テーブルの作成
CREATE TABLE book (
    bookid INTEGER NOT NULL PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(30) NOT NULL
);

-- データの登録
INSERT INTO book VALUES( 1, "Python No.1", "Python Taro");
INSERT INTO book VALUES( 2, "Python No.2", "Python Jiro");
INSERT INTO book VALUES( 3, "Python No.3", "Python Saburo");

-- データの選択と書名の取得
SELECT title FROM book WHERE bookid = 1;

いかがでしょうか、Databaseを扱うにはSQLをしっかり理解する必要がありそう、大変そう、だと思いませんか?

DjangoでDatabaseを使ってみよう

Djangoには、SQLの知識が少なくても、Databaseを操作できる仕組みがあります。

通常、Webアプリケーションを作る過程で、Databaseが必要になりますので、Djangoでも、Webアプリケーション(の枠組み)を作成してからDatabaseを操作するという流れになります。

書籍管理アプリの枠組みの作成

それでは、書籍を管理するWebアプリケーション(書籍管理アプリ)を作成しましょう。

最初にmysiteプロジェクトを作成します。

(1)端末で、アプリを配置したいディレクトリへ移動し、以下を実行します。

django-admin startproject mysite

(2)おまじないを実行します。

端末で、以下のコマンドを実行します。

cd mysite
python manage.py migrate

[実行結果]

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  (... 中略 ...)
  Applying sessions.0001_initial... OK

実は、未適用のマイグレーションファイルを適用しているのですが、ここではあまり関係ないので「おまじない」と思ってください。

ここまでの操作で、以下のようにmysiteフォルダが作成されます。

ツリー1

(3)開発用Webサーバーを起動します。

python manage.py runserver

以下のようなメッセージが表示されれば、開発用Webサーバーが起動できています。

[実行結果]

Performing system checks...

System check identified no issues (0 silenced).
March 07, 2018 - 20:56:49
Django version 2.0.3, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

開発用Webサーバーにアクセスしてみましょう。

(4)ブラウザを起動して、http://127.0.0.1:8000/にアクセスします。

開発用Webサーバーが動作していれば、以下のようなページが表示されます。

ItWorked

(5)端末で、CTRLキーを押しながらCキーを押します。

開発用Webサーバーが停止します。

それでは、書籍管理アプリの作成を続けましょう。

(6)端末で、以下のコマンドを実行します。

python manage.py startapp books

以下のように、booksディレクトリが作成されます。

Book作成

以上で、書籍管理アプリの枠組みが作成できました。

Databaseの準備

Djangoに用意されているDatabaseを操作できる仕組みマイグレーション)を使って、Databaseを作成していきましょう。

慣れない手順になっていますので、まずは概要を説明しておきます。

以下の図をご覧ください。

名称未設定

modelにテーブルレイアウトを記述し、makemigrationsコマンドを実行して、Databaseに対する変更指示書(migrationsファイル)を作成します。

次に、migrateコマンドを実行して、Databaseを準備するという流れです。

※注意:
SQLite以外のDatabaseを利用する場合は、あらかじめDatabaseを作成する必要があります。

たとえばMySQLを使用する場合は、後述の「Databaseの切り替え」の手順に従って、MySQLの準備をしてから、以下の操作を行ってください。

その他のDatabaseを利用する場合も、同様の準備が必要です。

準備ができたら、実際にマイグレーションをやってみましょう。

(1)model(books/models.py)にテーブルレイアウトを記述します。

books/models.pyの「# Create your models here」の下に以下の内容を記述します。

# Create your models here.
class Book(models.Model):
    # bookid : INTEGER型で、主キー
    bookid = models.IntegerField(primary_key=True)
    # 書名 : 文字列100桁
    title = models.CharField(max_length=100)
    # 著者 : 文字列30桁
    author = models.CharField(max_length=30)

(3)mysiteプロジェクトに、booksアプリを作成したことを伝えます。

mysite/settings.pyのINSTALLED_APPSの次に「’books.apps.BooksConfig’,」を追加します。

INSTALLED_APPS = [
    'books.apps.BooksConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

次に、端末で以下のコマンドを実行します。

python manage.py makemigrations books

[実行結果]

Migrations for 'books':
  books/migrations/0001_initial.py
    - Create model Book

これで、mysiteプロジェクトに対して、booksアプリのmodel(books/models.py)を変更したことを伝えられました。

ここまでの操作で、この後のmigrateコマンドを利用したときに実行されるSQL文が準備できました。

(4)SQL文を確認します。

以下のコマンドを実行してください。

python manage.py sqlmigrate books 0001

[実行結果]

BEGIN;
--
-- Create model Book
--
CREATE TABLE `books_book` (`bookid` integer NOT NULL PRIMARY KEY, `title` varchar(100) NOT NULL, `author` varchar(30) NOT NULL);
COMMIT;

SQLの知識が無くてもDatabaseが操作できそうな気がしますね!

この内容が、booksアプリのマイグレーションファイルに記録されていると考えてください。

(5)未適用のマイグレーションファイルを適用します。

python manage.py migrate

[実行結果]

Operations to perform:
  Apply all migrations: admin, auth, books, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
(省略)
  Applying books.0001_initial... OK
  Applying sessions.0001_initial... OK

「Applying books.0001_initial… OK」の行がキモです。

以上の操作で、SQL文を編集せずに、booksアプリにテーブルが作成されました。

さて、一連の流れを理解できたでしょうか?

この一連の流れは、Djangoを使ってWebアプリケーションを作成するときには、何度も出てくると思いますので、しっかり覚えておきましょう。

Djangoシェルを使ってみよう

Databaseへのデータの登録

次は、Djangoシェルを使って、Databaseにデータを登録してみましょう。

(1)Djangoシェルを起動します。

python manage.py shell

[実行結果]

Python 3.6.3 |Anaconda, Inc.| (default, Oct 13 2017, 12:02:49)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

(2)model(テーブルレイアウト)に基づいたオブジェクトを作成した後、オブジェクトの属性に値を設定し、そのオブジェクトをDatabaseのBookテーブルに保存します。

名称未設定

以下のようにコマンドを実行します。

In [1]: from books.models import Book

In [2]: b = Book(bookid=1, title="Python No.1", author="Python Taro")

In [3]: b.bookid
Out[3]: 1

In [4]: b.title
Out[4]: 'Python No.1'

In [5]: b.author
Out[5]: 'Python Taro'

In [6]:

オブジェクトbを作成したあと、b.bookidなどで属性を確認できました。

ここまでで、メモリ上にオブジェクトbが作成されましたので、オブジェクトbをテーブルに保存しましょう。

In [6]: b.save()

In [7]:

Databaseに登録したデータの表示

次に、テーブルに登録されているデータを確認します。

In [7]: Book.objects.all()
Out[7]: ]>

In [8]:

1件登録されていることがわかります。

せっかくなので、Book.objects.all()を実行したときに表示されるメッセージを変更してみましょう。

books/models.pyに__str__()メソッドを追加します。

__str__()メソッドは、書名(title)を返すだけの単純なメソッドです。

# Create your models here.
class Book(models.Model):
    # bookid : INTEGER型で、主キー
    bookid = models.IntegerField(primary_key=True)
    # 書名 : 文字列100桁
    title = models.CharField(max_length=100)
    # 著者
    author = models.CharField(max_length=30)
    #
    def __str__(self):
        return self.title

/books/models.pyを変更したら、Djangoシェルを再起動します。

In [8]:exit

python mange.py shell

[実行結果]

Python 3.6.3 |Anaconda, Inc.| (default, Oct 13 2017, 12:02:49)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

Book.objects.all()を実行してみましょう。

In [1]: from books.models import Book

In [2]: Book.objects.all()
Out[2]: ]>

In [3]:

書名が表示されましたね。

このように、models(books/models.py)では、modelに対するメソッドも定義できます。

開発用サーバを使ってみよう

Djangoには、グラフィカルな画面でデータを確認できる管理機能もあります。

この機能を使って登録したデータをメンテナンスしてみましょう。

管理者の登録

管理機能にログインするために、管理者を登録します。

(1)端末で、以下のコマンドを実行します。

python manage.py createsuperuser

[実行結果]

Username:

(2)ユーザー名を入力します。

Username: admin
Email address:

(3)メールアドレスを入力します。

Email address: samurai@example.com
Password:

(4)パスワードを2回入力します。

Password:
Password (again):
Superuser created successfully.

開発サーバの起動

端末で、以下のコマンドを実行します。

python manage.py runserver

Databaseに登録したデータの表示

何ごとにも準備は必要です。

(1)books/admin.pyの「# Register your models here.」以降を次のように変更します。

# Register your models here.
from .models import Book

admin.site.register(Book)

では、ブラウザを起動して、Databaseに登録したBookテーブルを表示してみましょう。

(2)ブラウザで「http://127.0.0.1:8000/admin」(または「http://localhost:8000/admin」)にアクセスします。

(3)管理者のユーザー名とパスワードを入力し、「Log in」をクリックします。

名称未設定

(4)「Books」をクリックします。

名称未設定

(5)「Python No.1」をクリックします。

名称未設定

Djangoシェルで登録したデータが表示されました。

名称未設定

ちなみに、この画面でデータの編集や削除もできます。

データを見ながら編集したいときは、この画面を使うと良いでしょう。

高度な内容に挑戦してみよう

少し高度な内容も紹介しておきますね。

Databaseの切り替え

Databaseにはいろいろな種類があり、MySQLが有名であることを紹介しました。

ここでは、Djangoが使用するデータベースをMySQLに変更する方法を説明します。

(1)PyMySQLパッケージをインストールします。

PyMySQLは、PythonからMySQLを操作するためにパッケージです。

pip install PyMySQL

(2)manage.pyの「import sys」の次に以下の2行を追加します。

import pymysql
pymysql.install_as_MySQLdb()

(3)MySQLの準備をします。

DJANGO Databaseを作成し、djangouserユーザー(パスワードは「password」)を作成して、DJANGO Databaseへのアクセス権限を付与します。

mysql -u root -p
Enter password: (パスワードを入力)
(省略)
mysql> CREATE DATABASE DJANGO;
Query OK, 1 row affected (0.00 sec)

mysql> CREATE USER djangouser IDENTIFIED BY "password";
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT ALL ON DJANGO.* TO djangouser@'%';
Query OK, 0 rows affected (0.00 sec)

後でDjangoのマイグレーションを行うと、DJANGO Databaseに、Djangoが必要とするテーブルが作成される仕組みです。

(4)プロジェクトの設定で、バックエンドをMySQLに変更します。

mysite/settings.pyのDATABASESを以下のように変更します。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'DJANGO',  # Database名
        'USER': 'djangouser',  # ユーザID
        'PASSWORD': 'password',  # ユーザIDのパスワード
        'HOST': 'localhost',  # ホスト名、別のホストを指定する場合は「xxx.xxx.xxx.xxx」のようにIPアドレスで指定できる
        'PORT': '3306',
    }
}

以上で、DjangoのDatabaseとして、MySQLが使用されるようになりました。

これ以降は、model(books/models.py)にテーブルレイアウトを記述するところから操作してください。

まとめ

この記事ではDjangoとDatabaseについて解説しました。

ちょっと高度な内容でしたが、MySQLを利用する際の設定方法も解説しましたね。

Djangoでアプリを開発する上で、Databaseは避けては通れない技術です。

この記事で取り上げた例は非常にシンプルですが、Databaseは奥深いものです。

皆さんも、まずは同じものを作って感覚を身につけて、皆さんなりのDatabaseを作ってみてくださいね!

この記事を書いた人

関西在住のITエンジニアです。普通の会社に勤務しながら、侍エンジニアのインストラクター、ライターとして活動しています。

目次