Python | Django | モデルを用いたデータベースからのデータ取得方法およびデータ集計方法
公開日:2021/7/5
Pythonには,DjangoというWebアプリケーションフレームワークがある.フレームワークのため,Djangoを利用するとWebアプリを通常よりも短時間で開発することが可能になる.
前記事にて,「モデルを用いた様々なテーブルからの値の取得方法」を記した.前記事での設定をそのまま引き継いだ上で,本記事では,「モデルを用いたデータベースからのデータ取得方法およびデータ集計方法」を以下にて記す.
なお,2021/6/29に「モデルを用いたデータベースからのデータ取得方法」の記事を作成している.本記事である「モデルを用いたデータベースからのデータ取得方法およびデータ集計方法」では,前回(6/29)よりも詳細なデータ取得方法や集計方法を記す.
- 準備
- データ取得方法
(1) AND条件・OR条件
(2) contain(部分一致)
(3) exclude(除外)
(4) order_by(並び替え)
(5) count(数を数える) - 基本的なデータ集計方法
- GROUP BYでのデータ集計方法
◆実施環境
Python 3.8.8
Django 3.2.3
■モデルを用いたデータベースからのデータ取得方法およびデータ集計方法
“model_project"に"query_process.py"を以下のように作成する.
“model_app/models.py"に記載されている内容は以下になる."models.py"の"many-to-one relationships"(多対1)を主に利用していく.そのため,以下45~46行目にコードを追加した.
from django.db import models
from django.utils import timezone
class
Date(models.Model):
# 抽象基底クラス
create_date = models.DateTimeField(default=timezone.now)
update_date = models.DateTimeField(default=timezone.now)
class
Meta:
abstract =
True
class
Cake(Date):
cake_name = models.CharField(max_length=40)
birthplace = models.CharField(max_length=40)
birthday = models.DateField(default='1900-01-01')
inventor = models.CharField(max_length=40)
sales_amounts = models.IntegerField()
like = models.BooleanField(default=True)
email = models.EmailField(db_index=True)
web_site = models.URLField()
feed_back = models.TextField(null=True,blank=True)
class
Meta:
db_table =
'cake'
index_together =
[['cake_name','inventor']]
ordering =
['birthday']
def
__str__(self):
return
f'{self.cake_name}'
# 以下"many-to-one relationships"の記載
class
Dorayakis(models.Model):
name = models.CharField(max_length=30)
price = models.IntegerField()
birthday = models.DateField(default='1900-01-01')
shop = models.ForeignKey(
'Shops', on_delete=models.RESTRICT
)
city = models.ForeignKey(
'Cities', on_delete=models.CASCADE
)
class
Meta:
db_table =
'dorayakis'
def __str__(self): # 今回追加箇所
return f'{self.id},{self.name}' # 今回追加箇所
class
Shops(models.Model):
name = models.CharField(max_length=30)
city = models.ForeignKey(
'Cities', on_delete=models.CASCADE
)
class
Meta:
db_table =
'shops'
class
Cities(models.Model):
name = models.CharField(max_length=30)
class
Meta:
db_table =
'cities'
# 以下"one-to-one relationships"の記載
class
Places(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class
Meta:
db_table =
'places'
class
Companies(models.Model):
place = models.OneToOneField(
Places,
on_delete=models.CASCADE,
primary_key=True
)
name = models.CharField(max_length=50)
class
Meta:
db_table =
'companies'
# 以下"many-to-many relationships"の記載
class
Musics(models.Model):
name = models.CharField(max_length=50)
def
__str__(self):
return self.name
class
Meta:
db_table =
'musics'
class
Musicians(models.Model):
name = models.CharField(max_length=30)
musics = models.ManyToManyField(Musics)
# ManyToManyFieldの利用
def
__str__(self):
return self.name
class
Meta:
db_table =
'musicians'
なお,現時点でのDBに含まれている値を以下に記す.
SQLiteをインストールし(詳細はこちら参照),"SQLITE EXPLORER"を開くと,各Table(“dorayakis", “shops", “cities")を以下赤枠にて確認できる.
上記赤枠のTable"dorayakis"を右クリックをし,"Show Table"をクリックすると,Tableに含まれている値の詳細は以下になる.
上記赤枠のTable"shops"を右クリックをし,"Show Table"をクリックすると,Tableに含まれている値の詳細は以下になる.
上記赤枠のTable"cities"を右クリックをし,"Show Table"をクリックすると,Tableに含まれている値の詳細は以下になる.
データ取得方法では,以下構成にてデータの取得方法を記す.
(1) AND条件・OR条件
(2) contain(部分一致)
(3) exclude(除外)
(4) order_by(並び替え)
(5) count(数を数える)
AND条件:複数の条件のいずれにも合致する値を取得する.
OR条件:複数の条件のいずれかに合致する値を取得する.
上記で作成した"query_process.py"を以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Dorayakis
# 1の処理(AND条件を利用したfilter)
print(Dorayakis.objects.filter(name='つぶあんどら焼き',city_id=2).all())
# 2の処理(AND条件を利用したfilter:query詳細確認)
print(Dorayakis.objects.filter(name='つぶあんどら焼き',city_id=2).all().query)
# 3の処理(OR条件を利用したfilter)
from django.db.models import Q
print(Dorayakis.objects.filter(Q(name='こしあんどら焼き') | Q(shop_id=4)).all())
# 4の処理(OR条件を利用したfilter:query詳細確認)
print(Dorayakis.objects.filter(Q(name='こしあんどら焼き') | Q(shop_id=4)).all().query)
■実行結果
# 1の結果
<QuerySet [<Dorayakis: 10,つぶあんどら焼き>,
<Dorayakis: 13,つぶあんどら焼き>, <Dorayakis: 16,つぶあんどら焼き>]>
# 2の結果
SELECT "dorayakis"."id", "dorayakis"."name", "dorayakis"."price",
"dorayakis"."birthday", "dorayakis"."shop_id", "dorayakis"."city_id"
FROM "dorayakis" WHERE
("dorayakis"."city_id" = 2 AND "dorayakis"."name" = つぶあんどら焼き)
# 3の結果
<QuerySet [<Dorayakis: 10,つぶあんどら焼き>,
<Dorayakis: 11,こしあんどら焼き>, <Dorayakis: 12,クリームどら焼き>,
<Dorayakis: 14,こしあんどら焼き>, <Dorayakis: 17,こしあんどら焼き>]>
# 4の結果
SELECT "dorayakis"."id", "dorayakis"."name", "dorayakis"."price",
"dorayakis"."birthday", "dorayakis"."shop_id", "dorayakis"."city_id"
FROM "dorayakis" WHERE
("dorayakis"."name" = こしあんどら焼き OR "dorayakis"."shop_id" = 4)
contain(部分一致):値の一部に合致する値を取得する.
“query_process.py"を以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Dorayakis
# 1の処理(containを利用したfilter)
print(Dorayakis.objects.filter(name__contains='あん').all())
# 1の処理(containを利用したfilter:query詳細確認)
print(Dorayakis.objects.filter(name__contains='あん').all().query)
■実行結果
# 1の結果
<QuerySet [<Dorayakis: 10,つぶあんどら焼き>,
<Dorayakis: 11,こしあんどら焼き>, <Dorayakis: 13,つぶあんどら焼き>,
<Dorayakis: 14,こしあんどら焼き>, <Dorayakis: 16,つぶあんどら焼き>,
<Dorayakis: 17,こしあんどら焼き>]>
# 2の結果
SELECT "dorayakis"."id", "dorayakis"."name", "dorayakis"."price",
"dorayakis"."birthday", "dorayakis"."shop_id", "dorayakis"."city_id"
FROM "dorayakis" WHERE "dorayakis"."name" LIKE %あん% ESCAPE '\'
exclude(除外):特定の値を除外した値を取得する.
“query_process.py"を以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Dorayakis
# 1の処理(excludeを利用)
print(Dorayakis.objects.exclude(name='つぶあんどら焼き').all())
# 2の処理(excludeを利用:query詳細確認)
print(Dorayakis.objects.exclude(name='つぶあんどら焼き').all().query)
■実行結果
# 1の結果
<QuerySet [<Dorayakis: 11,こしあんどら焼き>,
<Dorayakis: 12,クリームどら焼き>, <Dorayakis: 14,こしあんどら焼き>,
<Dorayakis: 15,クリームどら焼き>, <Dorayakis: 17,こしあんどら焼き>,
<Dorayakis: 18,クリームどら焼き>]>
# 2の結果
SELECT "dorayakis"."id", "dorayakis"."name", "dorayakis"."price",
"dorayakis"."birthday", "dorayakis"."shop_id", "dorayakis"."city_id"
FROM "dorayakis" WHERE NOT ("dorayakis"."name" = つぶあんどら焼き)
order_by(並び替え):特定の並び替えに基づき値を取得する.
“query_process.py"を以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Dorayakis
# 1の処理(order_byを利用)
print(Dorayakis.objects.order_by('-shop_id').all())
# 2の処理(order_byを利用:query詳細確認)
print(Dorayakis.objects.order_by('-shop_id').all().query)
■実行結果
# 1の結果
<QuerySet [<Dorayakis: 18,クリームどら焼き>,
<Dorayakis: 17,こしあんどら焼き>, <Dorayakis: 16,つぶあんどら焼き>,
<Dorayakis: 15,クリームどら焼き>, <Dorayakis: 14,こしあんどら焼き>,
<Dorayakis: 13,つぶあんどら焼き>, <Dorayakis: 12,クリームどら焼き>,
<Dorayakis: 11,こしあんどら焼き>, <Dorayakis: 10,つぶあんどら焼き>]>
# 2の結果
SELECT "dorayakis"."id", "dorayakis"."name", "dorayakis"."price",
"dorayakis"."birthday", "dorayakis"."shop_id", "dorayakis"."city_id"
FROM "dorayakis" ORDER BY "dorayakis"."shop_id" DESC
count(数を数える):特定の数を数えて,出力する.
“query_process.py"を以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Dorayakis
# 1の処理(countを利用)
print(Dorayakis.objects.count())
# 2の処理(nameが合致する値についてcountを利用)
print(Dorayakis.objects.filter(name='つぶあんどら焼き').count())
■実行結果
# 1の結果
9
# 2の結果
3
(1) Count: 数を数える
(2) Max: 最大値を取得する
(3) Min: 最小値を取得する
(4) Avg: 平均値を取得する
(5) Sum: 積算値を取得する
“query_process.py"を以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Dorayakis
# 1の処理
from django.db.models import Count, Max, Min, Avg, Sum
print(Dorayakis.objects.aggregate(
Count('shop_id'),Max('shop_id'),
Min('shop_id'),Avg('shop_id'),
Sum('shop_id'))
)
# 2の処理
print(Dorayakis.objects.aggregate(
count_shop_id=Count('shop_id'),
max_shop_id=Max('shop_id'),
min_shop_id=Min('shop_id'),
avg_shop_id=Avg('shop_id'),
sum_shop_id=Sum('shop_id'))
)
■実行結果
# 1の結果
{'shop_id__count': 9, 'shop_id__max': 6, 'shop_id__min': 4,
'shop_id__avg': 5.0, 'shop_id__sum': 45}
# 2の結果
{'count_shop_id': 9, 'max_shop_id': 6, 'min_shop_id': 4,
'avg_shop_id': 5.0, 'sum_shop_id': 45}
“GROUP BY"は"values"と"annotate"を利用する.以下は名前を集計し,名前ごとに"shop_id"の最大値を出力することを意味している.
「values.('name’).annotate(Max('shop_id’))」
“query_process.py"を以下のように編集する.
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','model_project.settings')
from django import setup
setup()
from model_app.models import Dorayakis
from django.db.models import Count, Max, Min, Avg, Sum
# 1の処理
print(Dorayakis.objects.values('name').annotate(
Max('shop_id'), Min('shop_id')
))
■実行結果
# 1の結果
<QuerySet
[{'name': 'こしあんどら焼き', 'shop_id__max': 6, 'shop_id__min': 4},
{'name': 'つぶあんどら焼き', 'shop_id__max': 6, 'shop_id__min': 4},
{'name': 'クリームどら焼き', 'shop_id__max': 6, 'shop_id__min': 4}]>
■参照
https://docs.djangoproject.com/en/3.2/topics/db/aggregation/
以上