Database Support Blog

  • EDB
  • PostgreSQL
2021.12.09

Pythonの「Django」とPostgreSQLを接続してデータベースにアクセスしてみた!

当記事はエンタープライズDB社のブログ記事の翻訳の紹介および弊社考察を加えています。

この記事ではPythonの WebアプリケーションフレームワークであるDjangoからPostgreSQLのデータにアクセスする方法をご紹介します。また、Djangoのインストール方法の説明後、簡単なDjangoアプリケーションを作成する方法をご紹介します。

 1. はじめに
 2. 仮想環境の作成
 3. Djangoのインストール
 4. DjangoでPostgreSQLを使った簡単なアプリを作る


Web開発の黎明期には、Webアプリケーションの多くで LAMP(Linux+Apache+MySQL+PHP)というフレームワークが選ばれていました。 PHP は今でも素晴らしいコーディング言語ですが、昨今ではPythonの人気が非常に高まっています。きれいな構文を持ち、さまざまな業界で使用されているPythonは、新たに開発を行う際の選択肢の1つとなっています。この記事では、Python用の人気Webアプリケーションフレームワークである「Django」からPostgresに接続する方法をご紹介します。


はじめに

本記事でご紹介するPython を使用する際には、以下のような注意点がありますので予めご確認ください。

・Python の「仮想環境」を使用することを強くお勧めします。
 システム内に仮想環境を用意することで、バージョン変更で発生するライブラリやパッケージの依存関係の問題を防ぐことができます。

・Python 2は2020年1月1日にPythonコミュニティによって廃止されました。
 PostgreSQLコミュニティもPostgreSQL13以降plpython v2を提供していません。

・EDB Postgres Advanced Server(EPAS)14ではplpython v2をサポートしません
 EPAS13まではplpython v2をサポートしていましたが、EPAS 14では利用できなくなるためPython v3の利用を強く推奨します。また、当記事では、Python v.3.x がインストールされていること、Postgres インスタンスが稼働していることを前提としていますので、ご承知おきください。


仮想環境の作成

Django を使用するための最初のステップは「仮想環境」の作成です。まだ「virtualenv」がインストールされていない場合は「pip」でインストールします。

 
 sudo pip install virtualenv
 

ここでは「/var」ディレクトリに「myproject」というプロジェクト用のフォルダを作成します。

 
 mkdir /var/myproject
 cd /var/myproject
 

そして「virtualenv」を使って仮想環境を作る必要があります。

 
 [root@pga /]# virtualenv /var/myproject/myprojectenv
  
 Using base prefix '/opt/rh/rh-python36/root/usr'
  
 New python executable in /var/myproject/myprojectenv/bin/python3
  
 Also creating executable in /var/myproject/myprojectenv/bin/python
  
 Installing setuptools, pip, wheel...done.
  
 [root@pga /]# ls /var/myproject/myprojectenv/
  
 bin  include  lib  lib64
 

作成した仮想環境を起動(有効化)するために activate を実行します。

 
 [root@pga /]# python --version
  
 Python 2.7.5
  
 [root@pga /]# source /var/myproject/myprojectenv/bin/activate
  
 (myprojectenv) [root@pga /]# python --version
  
 Python 3.6.3
 

Python から Postgres に接続するには "psycopg2" モジュールをインストールする必要がありますが、そのために、まずは OS に pg_config がインストールされている必要があります。

 
 [root@pga /]# pg_config
  
 bash: pg_config: command not found
  
 [root@pga /]# export PATH=/usr/pgsql-12/bin/:${PATH}
  
 [root@pga /]# which pg_config
  
 /usr/pgsql-12/bin/pg_config
 

OS 上に pg_config が見つからない場合、まず Postgres クライアントをインストールする必要があります。システム上で pg_config が利用可能であることを確認した後に「psycopg2」をインストールしてください。

 
 # pip install psycopg2
  

Djangoのインストール

仮想環境を有効化した後、その環境に次のように Django をインストールすることで、プロジェクトのファイルがホスト OS と干渉しないようにします。

 
 # pip install django
 

Django のインストールが完了したら、新しい Django プロジェクトを開始します。

 
 (myprojectenv) [root@pga bin]# pwd
 
 /var/myproject/myprojectenv/bin
 
 (myprojectenv) [root@pga bin]# django-admin.py startproject myproject .
 

デフォルトでは、Django はバックエンドのデータベースとして SQLite を使うように設定されています。Postgres を使うには "myproject/settings.py" を更新する必要があります。

 
 # cat myproject/settings.py
  
 . . .
  
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.postgresql_psycopg2',
         'NAME': ‘<db_name>’,
         'USER': '<db_username>',
         'PASSWORD': '<password>',
         'HOST': '<db_hostname_or_ip>',
         'PORT': '<db_port>',
     }
 }
 . . .
 

※表示の都合上、HTMLタグを全角括弧で表記しています。

Postgres データベースへの接続設定が完了したら、続いてデフォルトのスキーマを構築します。Django はユーザーアクセスを念頭に置いて設計されているため、デフォルトで、Django アプリケーションに必要なユーザ、グループ、権限を含むデータベーススキーマを作成します。スキーマの作成を進めるには、マイグレーションファイルをを生成してそれを実行します。

  
 (myprojectenv) [root@pga bin]# python manage.py makemigrations
  
 No changes detected
  
 (myprojectenv) [root@pga bin]# 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 admin.0001_initial... OK
  
   Applying admin.0002_logentry_remove_auto_add... OK
  
   Applying admin.0003_logentry_add_action_flag_choices... OK
  
   Applying contenttypes.0002_remove_content_type_name... OK
  
   Applying auth.0002_alter_permission_name_max_length... OK
  
   Applying auth.0003_alter_user_email_max_length... OK
  
   Applying auth.0004_alter_user_username_opts... OK
  
   Applying auth.0005_alter_user_last_login_null... OK
  
   Applying auth.0006_require_contenttypes_0002... OK
  
   Applying auth.0007_alter_validators_add_error_messages... OK
  
   Applying auth.0008_alter_user_username_max_length... OK
  
   Applying auth.0009_alter_user_last_name_max_length... OK
  
   Applying auth.0010_alter_group_name_max_length... OK
  
   Applying auth.0011_update_proxy_permissions... OK
  
   Applying sessions.0001_initial... OK
  
 (myprojectenv) [root@pga bin]# 
 

続いてデフォルトのスーパーユーザーを作成します。

 
 (myprojectenv) [root@pga bin]# python manage.py createsuperuser
  
 Username (leave blank to use 'root'): richyen
  
 Email address: support@enterprisedb.com
  
 Password: 
  
 Password (again): 
  
 Superuser created successfully.
  
 (myprojectenv) [root@pga bin]#
 

ここまできたらアプリケーションを起動することができます。
次のように接続を受け付けるポートを指定して、アプリケーションを起動します。

 
 (myprojectenv) [root@pga bin]# python manage.py runserver 0.0.0.0:5000
  
 Watching for file changes with StatReloader
 Performing system checks...
  
 System check identified no issues (0 silenced).
 December 06, 2019 - 07:06:22
 Django version 3.0, using settings 'myproject.settings'
 Starting development server at http://0.0.0.0:5000/
 Quit the server with CONTROL-C.
 

上記画面が表示されればアプリケーションの起動は成功です。

スーパーユーザーでの動作を確認するためには「/admin」ページにアクセスします。

スーパーユーザーのユーザー/パスワードで管理サイトにログインすることができます。


DjangoでPostgreSQLを使ったシンプルなアプリを作る

前述のステップで Django を起動し、Postgres に接続することができました。では Django をさらに構築し、ORM を使ってデータベースとやり取りするにはどうすればよいでしょうか?

車とその所有者の関係を表示するアプリを作ってみましょう。

 
 (myprojectenv) [root@pga bin]# python manage.py startapp cars
 

これにより、以下の重要なファイルで構成された「cars」というフォルダが作成されます。

 
 (myprojectenv) [root@pga bin]# cd cars/
 (myprojectenv) [root@pga cars]# ls -l
  
 total 24
  
 -rw-r--r-- 1 root root   63 Dec  6 07:29 admin.py
 -rw-r--r-- 1 root root   94 Dec  6 07:29 apps.py
 -rw-r--r-- 1 root root    0 Dec  6 07:29 __init__.py
 drwxr-xr-x 2 root root 4096 Dec  6 07:29 migrations
 -rw-r--r-- 1 root root   57 Dec  6 07:29 models.py
 -rw-r--r-- 1 root root   60 Dec  6 07:29 tests.py
 -rw-r--r-- 1 root root   63 Dec  6 07:29 views.py
 

「models.py」を定義して、車と所有者がどのように見えるかをフレームワークに伝えます。

 
 (myprojectenv) [root@pga bin]# cat cars/models.py 
  
 from django.db import models
  
 class Driver(models.Model):
     name = models.TextField()
     license = models.TextField()
  
 class Car(models.Model):
     make = models.TextField()
     model = models.TextField()
     year = models.IntegerField()
     vin = models.TextField()
     owner = models.ForeignKey("Driver", on_delete=models.SET_NULL, null=True)
 

そして、データベースのテーブルを構築するためにマイグレーションを実行します。

 
 (myprojectenv) [root@pga bin]# python manage.py makemigrations cars
  
 Migrations for 'cars':
   cars/migrations/0001_initial.py
     - Create model Driver
     - Create model Car
  
 (myprojectenv) [root@pga bin]# python manage.py migrate cars
  
 Operations to perform:
   Apply all migrations: cars
  
 Running migrations:
   Applying cars.0001_initial... OK
 
 

データベースを見ると、「<プロジェクト名>_<オブジェクト名>」というフォーマットでテーブルが作成されていることが確認できます。

 
 postgres=# \d
  
                      List of relations
  
  Schema |            Name             |   Type   |  Owner   
 --------+-----------------------------+----------+----------
  public | auth_group                  | table    | postgres
  public | auth_group_id_seq           | sequence | postgres
  
 <...>
  
  public | cars_car                    | table    | postgres
  public | cars_car_id_seq             | sequence | postgres
  public | cars_driver                 | table    | postgres
  public | cars_driver_id_seq          | sequence | postgres
 

このチュートリアルのために次のランダムなデータを作成しました。

 
 postgres=# select * from cars_driver;
  
  id |   name   | license  
 ----+----------+----------
   1 | John Doe | Z1234567
   2 | Jane Doe | Z9876543
  
 (2 rows)
  
  
 postgres=# select * from cars_car;
  
  id |  make  | model  | year |               vin                | owner_id 
 ----+--------+--------+------+----------------------------------+----------
   1 | Ford   | F-150  | 2004 | 01083da2df15d6ebfe62186418a76863 |        1
   2 | Toyota | Sienna | 2014 | 53092a17afa460689ca931f0d459e399 |        1
   3 | Honda  | Civic  | 2018 | 844c56840b5fc26d414cf238381a5f1a |        2
   4 | GMC    | Sierra | 2012 | 29aeffa4d5aa21d25d7196db3728f72c |        2
  
 (4 rows)
 

次に、「cars/views.py」を編集し、データベースからデータを取り出して表示する方法を Django に伝えます。

  
 (myprojectenv) [root@pga cars]# cat views.py 
  
 from django.shortcuts import render
 from cars.models import Car, Driver
  
 def car_detail(request, pk):
     owner_obj = Driver.objects.get(pk=pk)
     car_objs = Car.objects.filter(owner_id=owner_obj.id)
     context = {
         "vehicles": car_objs,
         "drivers": owner_obj,
     }
     return render(request, "car_detail.html", context)
 

「views.py」のプロシージャがデータを Web ページとして表示するためには、テンプレートを定義する必要があります。まず、HTMLページの一般的な要素を含む「cars/template/base.html」ファイルを作成します。

 
 (myprojectenv) [root@pga cars]# cat templates/base.html 
  
 <!doctype html>
 <html>
     <head>
         <meta charset="utf-8">
         <meta name="viewport" content="width=device-width, initial-scale=1">
  
         <title>Contacts</title>
         <link rel="stylesheet" href="https://unpkg.com/tachyons@4.10.0/css/tachyons.min.css"/>
     </head>
     <body>
  
 {% block page_content %}{% endblock %}
  
     </body>
 </html>
 

※表示の都合上、HTMLタグを全角括弧で表記しています。

次に、実際にデータを表示するための「car_detail.html」テンプレートを定義します。

 
 (myprojectenv) [root@pga cars]# cat templates/car_detail.html 
  
 {% extends "base.html" %}
  
 {% block page_content %}
         <div class="mw6 center pa3 sans-serif">
  
             <h1 class="mb4">Driver: {{ drivers.name | linebreaks }}</h1>
             <header class="b mb2">License: {{ drivers.license }}</header>
  
         {% for v in vehicles %}
  
             <div class="pa2 mb3 striped--near-white">
                 <div class="pl2">
                     <p class="mb2">Make/Model: {{ v.make }} {{ v.model }}</p>
                     <p class="mb2">Year: {{ v.year }}</p>
                     <p class="mb2">Vin: {{ v.vin }}</p>
                 </div>
             </div>
  
         {% endfor %}
  
         </div>
 {% endblock %}
 

※表示の都合上、HTMLタグを全角括弧で表記しています。

最後に、トラフィックをどのようにルーティングするかウェブサーバに伝える必要があります。
それにはまず、「cars/urls.py」で REST がどのように機能するかを定義します。

 
 (myprojectenv) [root@pga cars]# cat urls.py 
  
 from django.urls import path
 from . import views
  
  
 urlpatterns = [
     path("<int:pk>/", views.car_detail, name="car_detail"),
 ]
 

これで、URL で提供された ID に基づいて “車” と ”所有者” オブジェクトを取得できるようになります。

次に、「myproject/urls.py」で、「cars」アプリケーションのルートURLを定義します。

 
 from django.contrib import admin
 from django.urls import path, include
  
 urlpatterns = [
     path('admin/', admin.site.urls),
     path("cars/", include("cars.urls")),
 ]
 

「myproject/settings.py」の「INSTALLED_APPS」リストに「cars」を追加して、Django に「cars」アプリがアクティブであることを伝え、Webサーバを起動します。

 
 (myprojectenv) [root@pga bin]# python manage.py runserver 0.0.0.0:5000
  
 Watching for file changes with StatReloader
 Performing system checks...
  
 System check identified no issues (0 silenced).
 December 09, 2019 - 23:53:09
 Django version 3.0, using settings 'myproject.settings'
 Starting development server at http://0.0.0.0:5000/
 Quit the server with CONTROL-C.
 

無事に起動したら、http://127.0.0.1:5000/cars/1 にアクセスすることができます。

URLの "1 "を "2 "に変更すると、”id=2” の所有者と所有する車のデータを取得できます。

これは、Django を使って PostgreSQL のデータを Web ページに提供する簡単な例です。Django から PostgreSQL のデータにアクセスする方法 (複雑な結合や複雑なフィルタリング、等) の詳細は Django のドキュメント をご参照ください。

(以上、EDB社ブログ記事より翻訳)


まとめ

人気の高い言語 Python の Web アプリケーションフレームワーク(Django)を使って PostgreSQL のデータを Web ページとして表示する方法をご紹介いたしました。ご紹介させていただいた内容は簡易的な実装ですので、実際はこれらをもとに独自に組み込みを行うことになると思いますが、本記事が Django から PostgreSQL のデータにアクセスする理解の一助になれば幸いです。


執筆者情報

やすだこうき プロフィール画像

2017年に中途入社。Oracle Database、EDB Postgres/PostgreSQL のサポート経験を経て、2020年からバックサポートを担当。DBとアプリケーションを繋ぐミドルウェア製品のスペシャリスト。トレンドな技術は積極的に触れるほど好奇心旺盛。最近はプロアクティブなサポートを目指して粉骨砕身。趣味はボードゲーム。...show more


■本記事の内容について
 本記事に示した定義及び条件は変更される場合があります。あらかじめご了承ください。

■商標に関して
 ・Oracle®、Java、MySQL及びNetSuiteは、Oracle、その子会社及び関連会社の米国及びその他の国における登録商標です。
 ・Amazon Web Services、AWS、Powered by AWS ロゴ、[およびかかる資料で使用されるその他の AWS 商標] は、Amazon.com, Inc. またはその関連会社の商標です。
  文中の社名、商品名等は各社の商標または登録商標である場合があります。

関連している記事

  • EDB
  • PostgreSQL
2024.01.16

EDBがもたらすデータベースの新たな価値 ~ EDB社Field CTO Ajit Gadge氏来日、セミナー講演レポート ~

EDB社のAjit Gadge氏を招き「PostgreSQLユーザーに捧ぐ、EDBを使ったDB機能向上とコスト削減の両立」セミナーを開催しました。DB市場の現状やトレンド、EDBの最新動向について紹介しております。アシストセッションのアーカイブ配信の視聴申し込みも可能です。ぜひご覧ください。

  • PostgreSQL
  • EDB
2023.12.20

PostgreSQLのSQLチューニングを体験してみよう!

35年以上教育事業を展開しているアシストが新たに取り組み始めた「ポスグレ学園」。連載最終回となる9回目の記事では、「PostgreSQL SQLチューニング実践」のワークショップ主管である 田中 健一朗 にインタビューしました。

  • PostgreSQL
  • EDB
2023.10.30

データベースの健康診断! ~ PostgreSQL DB稼働分析体験 ~

35年以上教育事業を展開しているアシストが新たに取り組み始めた「ポスグレ学園」。連載8回目となる今回の記事では、PostgreSQL DB稼働分析ワークショップの主管である保田 公貴にインタービューしました。

ページの先頭へ戻る