こんにちは!インストラクターの本多です。
皆さんは、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 | 書名 | 著者 |
---|---|---|
1 | Python No.1 | Python Taro |
2 | Python No.2 | Python Jiro |
3 | Python No.3 | Python Saburo |
そこでテーブルを、以下のように定義します。
論理名 | 物理名 | データ型 | 主キー |
---|---|---|---|
BookID | bookid | INTEGER (整数) | ○ |
書名 | title | VARCHAR(100) (文字列100バイト) | |
著者 | author | VARCHAR(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フォルダが作成されます。
(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サーバーが動作していれば、以下のようなページが表示されます。
(5)端末で、CTRLキーを押しながらCキーを押します。
開発用Webサーバーが停止します。
それでは、書籍管理アプリの作成を続けましょう。
(6)端末で、以下のコマンドを実行します。
python manage.py startapp books
以下のように、booksディレクトリが作成されます。
以上で、書籍管理アプリの枠組みが作成できました。
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を作ってみてくださいね!