SlideShare a Scribd company logo
1 of 131
Download to read offline
開始前スライド:目次

対象:初心者

第一部:データを取得しよう!

第二部:親や子のモデルへのアクセス

第三部:select_relatedとprefetch_related

第四部:集計/集約

第五部:応用編:JsonFieldへのクエリ発行(※PostgreSQL限定)

MAKE QUERY GREAT AGAIN!
Django Congress JP 2019
@pro_proretariat
Omae Dare YO?
Profile = namedtuple('Profile', ('name', 'age',
'company', 'prefectures',
'twitter', 'features'))
Profile(name='Nakajima Yuuki',
age=34,
company='日本システム技研',
prefectures='Nagano',
twitter='pro_proletariat',
features='20代はC0B0LERでした、Django歴は3年ぐらい'
)
正直この規模の登壇経験がない上に、ネタっぽいタイトルが自分
しかいないので震えてます((((;゚Д゚))))

アジェンダ

・話すこと

 ・Djangoでselect文を書く方法

 ・簡単なwhere句から集計・集約まで



アジェンダ

・話すこと

 ・Djangoでselect文を書く方法

 ・簡単なwhere句から集計・集約まで

・話さないこと

 ・SQLの詳しい説明

 ・O/RMの是非

アジェンダ

・話すこと

 ・Djangoでselect文を書く方法

 ・簡単なwhere句から集計・集約まで

・話さないこと

 ・SQLの詳しい説明

 ・O/RMの是非

・話したいけど話さないこと

 ・サブカル最前線

 ・ライブアイドルとその魅力

今回話そうと思ったきっかけ

・Django初心者の人がSQLを直書きしていた

・自分自身、よく分からずにググってコピペして乗り切っていた

・Django人口が増えてきたので初級的な話しは需要がありそう

目指すこと

なるべくSQLを書かない!

環境

● Python3.7

● Django2.1.7

● PostgresSQL11.0

目次

第一部:データを取得しよう! 🍣

第二部:親や子のモデルへのアクセス

第三部:select_relatedとprefetch_related

第四部:集計/集約

第五部:JsonFieldへのクエリ発行(※PostgreSQL限定)

大将『お客を増やすためにSNS炎上を繰り返したら大
変なことになってしまったんだ』

ある日寿司屋にて・・・・

ヤバいお寿司屋さん
ウエブサイト 経路案内 保存
1.0 ☆☆☆☆☆
口コミ(2,147,483,647)

所在地:ゴッサムシティ路地裏通り 3丁目
大将『きちんと経営を見直したいからまずお品書きを
webで管理したい』

models.py

class SushiTopping(models.Model):
"""タコ、サワラ、シメサバなどの具材"""
name = models.CharField(max_length=255)
class Menu(models.Model):
"""お品書き"""
name = models.CharField(max_length=255, unique=True)
price = models.IntegerField(default=0)
sushi_toppings = models.ManyToManyField(SushiTopping)
class Sale(models.Model):
sales_date = models.DateTimeField()
menu = models.ForeignKey(Menu, on_delete=models.PROTECT)
実際のデータベース

sqlite> .tables
auth_group django_content_type
auth_group_permissions django_migrations
auth_permission django_session
auth_user sales_menu
auth_user_groups sales_menu_sushi_toppings # 中間テーブル
auth_user_user_permissions  sales_sale
django_admin_log sales_sushitopping
sqlite>
大将『メニューを全件表示して欲しい』

全件取得: Model.objects.all()

Menu.objects.all()
SELECT ...(略)... FROM sales_menu;


id | name | price 

----+----------------------+--------- 

1 | トロ | 4996 

2 | サーモン | 4335 

3 | 炙りサーモン | 7326 

...(略)...

15 | 裏メニュー | 5000000 



大将:「価格が高い順番に並べてよ」

ソート: order_by('field_name') 

Menu.objects.all().order_by('-price')
SELECT ...(略)... FROM sales_menu ORDER BY price DESC;
id | name | price | features 

----+----------------------+---------+---------- 

15 | 裏メニュー | 5000000 | 

8 | アナゴ | 5055 | 

...(略)... 

4 | 炙りシメサバ | 126 | 

13 | オススメコース | 0 | 

大将:「商品名で検索したいんだけど」

絞り込み:filter()

Menu.objects.filter(name="カリフォルニアロール")
SELECT (略) FROM sales_menu WHERE name = 'カリフォルニアロール';
id name price
---------- ------------------------------ ----------
9 カリフォルニアロール 8744
大将:「サーモン以外のデータとか出して欲しい
んだけど」

NOT条件で絞り込み:exclude()

Menu.objects.exclude(name="サーモン")
SELECT ...(略)... FROM sales_menu WHERE not (name = 'サーモン');
id | name | price
----+----------------------+---------
3 | 炙りサーモン | 7326
4 | 炙りシメサバ | 126
6 | シメサバ | 1843
大将:「2000円以上とかイカとか」

大将:「トロで検索したら大トロも中トロもだして」

Field lookups 

Field lookups are how you specify the meat of an SQL WHERE
clause.
https://docs.djangoproject.com/ja/2.2/ref/models/querysets/#field-lookups
フィールドルックアップは、SQLのWHERE句の中身を指定
する方法です。



where句の条件の指定方法:field_name__[取得方法]=value

Menu.objects.filter(price__gte=2000) # 2000円以上 -> Greater Than
Like検索: contains

# 大トロ、中トロ
Menu.objects.filter(name__contains="トロ")
その他は公式をチェック

https://docs.djangoproject.com/en/2.1/ref/models/querysets/#field-lookups
https://docs.djangoproject.com/en/2.2/ref/models/querysets/#field-lookups
大将:「はまち か 2000円以下で検索みたいな
ことしたいんだけど」

Qオブジェクト

from django.db.models import Q
q = Q(name="ハマチ")
q |= Q(price__lt=2000) # |= でor &= でand
Menu.objects.filter(q)
SELECT ...(略)... FROM sales_menu
WHERE (name = “ハマチ” OR price < 2000);
補足:Qオブジェクトが力を発揮するのは処理の中

q = Q(name="サーモン")
if is_hungry:
q |= Q(name="オススメコース")
  Menu.objects.filter(q)
大将:「色々ありがとう、これでお品書きの管理
ができるよ」

・全件取得 : Model.objects.all()
・ソート : Model.objects.all().order_by('field_name')
・普通の絞り込み:Model.objects.filter(field_name="value")
・色々な絞り込み:Model.objects.filter(field_name__[取得方法]="value")
・Qオブジェクト: Model.objects.filter(Q(field="value"))
第一部まとめ

一度休憩

● 一度お水を飲んで落ち着け

● ペースはあってる?

● 早口になってない?

おまけSQLの確認方法 query

SELECT
...(略)...
FROM
sales_menu
WHERE
name 'マグロ';
print(Menu.objects.filter(name="マグロ").query)

目次

第一部:データを取得しよう! 🏅

第二部:親や子のモデルへのアクセス 🍣

第三部:select_relatedとprefetch_related

第四部:集計/集約

第五部:JsonFieldへのクエリ発行(※PostgreSQL限定)

大将:「売上げの一覧も出してくれよな」

models.py

class SushiTopping(models.Model):
"""タコ、サワラ、シメサバなどのトッピング"""
name = models.CharField(max_length=255)
class Menu(models.Model):
"""お品書き"""
name = models.CharField(max_length=255, unique=True)
price = models.IntegerField(default=0)
sushi_toppings = models.ManyToManyField(SushiTopping)
class Sale(models.Model):
sales_date = models.DateTimeField()
menu = models.ForeignKey(Menu, on_delete=models.PROTECT)
models.py

class SushiTopping(models.Model):
"""タコ、サワラ、シメサバなどのトッピング"""
name = models.CharField(max_length=255)
class Menu(models.Model):
"""お品書き"""
name = models.CharField(max_length=255, unique=True)
price = models.IntegerField(default=0)
sushi_toppings = models.ManyToManyField(SushiTopping)
class Sale(models.Model):
sales_date = models.DateTimeField()
menu = models.ForeignKey(Menu, on_delete=models.PROTECT)
一覧取得はobjects.all()でイナフ

Sale.objects.all()
SELECT ...(略)... FROM sales_sale;
id | sales_date | menu_id 

----+------------------------+--------- 

1 | 2019-02-02 06:11:26+00 | 9 

2 | 2019-05-07 12:26:06+00 | 14 

3 | 2019-01-03 19:02:25+00 | 3 

...(略)...

899 | 2019-03-16 17:17:54+00 | 2 

900 | 2019-03-23 11:34:56+00 | 14 





大将:「お品書きも出してよ?」

やりたいこと

id name
1 マグロ
id 売上げ日時 menu_id
1 2019/05/16 1
ID 売上げ日時 menu.name
1 2019/05/16 マグロ
Menu
Sale

s = Sale.objects.get(id=1)
s.menu.name
>タマゴヤキ
親モデルの取得:object.[ForeignKeyField]

models.py
class Menu(models.Model):
pass
class Sale(models.Model):
menu = models.ForeignKey(Menu, on_delete=models.PROTECT)
id name
1 マグロ
id 売上げ日時 menu_id
1 2019/05/16 1
Menu

Sale

①s = Sale.objects.get(id=1)
①取得

Django
id name
1 マグロ
id 売上げ日時 menu_id
1 2019/05/16 1
Menu

Sale

①s = Sale.objects.get(id=1)
②s.menu.name
①取得

②取得

Django
where menu_id=1
● ドットで感覚的にアクセスできる

● 実はJoinしていない

● Python側で親のオブジェクトを1件取得している

親モデルへのアクセスまとめ

大将:「お品書きから売上げ一覧をだして欲しいな」

やりたいこと:親(menu)から子(Sale)をもとめる

id name
1 マグロ
id 売上げ日時 menu_id
1 2019/05/16 1
2 2019/05/15 2
3 2019/05/19 1
Menu
 Sale

id 売上げ日時 menu_id
1 2019/05/16 1
2 2019/05/15 2
3 2019/05/19 1
親から子: .[子のモデル]_set.all()

m = Menu.objects.get(id=1)
m.sale_set.all()
SELECT 略 FROM sales_sale WHERE menu_id = 1;
id | sales_date | menu_id
-----+------------------------+---------
7 | 2019-02-24 20:53:55+00 | 1
27 | 2019-04-14 06:58:29+00 | 1
m = Menu.objects.get(id=1)
m.sale_set.all()
親→子

子→親

SQLは どちらも同じ

Sale.objects.filter(menu_id=1)
親から子の取り方

● 親→子なので複数レコード取得される

● まとまり(セット)で取得するから_setとつける

● obj.[子のモデル名]_set.all()

まとめ
● 子から親へのアクセス

○ 子モデル.ForeignKeyField

○ Sale.menu.name

● 親から子へのアクセス(複数レコード) 

○ 親モデル.子モデル_set.all()

○ menu.sale_set.all()

大将:「メニューに具材の名前もだしてくれよな」

models.py

class SushiTopping(models.Model):
pass
class Menu(models.Model):
sushi_toppings = models.ManyToManyField(SushiTopping)
ManyToMany(多対多)って何?

🐟
🦑
🥑
お任せ2貫🐟🦑

マグロ 🐟

アボガド 🥑

寿司トッピング
 お品書き

多対多:ManyToMany(M2M) 

🐟
🦑
🥑
お任せ2貫🐟🦑

マグロ 🐟

アボガド 🥑

寿司トッピング
 お品書き

トッピング お品書き
🐟 🐟
🐟 🐟🦑
中間テーブル

多対多:ManyToMany(M2M) 

🐟
🦑
🥑
お任せ2貫🐟🦑

マグロ 🐟

アボガド 🥑

寿司トッピング
 お品書き

トッピング お品書き
🐟 🐟
🐟 🐟🦑
🦑 🐟🦑

中間テーブル

多対多:ManyToMany(M2M) 

🐟
🦑
🥑
お任せ2貫🐟🦑

マグロ 🐟

アボガド 🥑

寿司トッピング
 お品書き

トッピング お品書き
🐟 🐟
🐟 🐟🦑
🦑 🐟🦑

🥑 🥑
中間テーブル

やること:Menuが持つ寿司トッピングを取得

id 品書き
2 🐟🦑お任せ2貫
トッピング お品書き
🐟 🐟🦑お任せ2貫
🦑 🐟🦑お任せ2貫

Menu
 中間テーブル

id Menu トッピング
2 🐟🦑お任せ2貫 🐟
2 🐟🦑お任せ2貫 🦑
ManyToMany(M2M)のモデル取得:M2M_field.all()

Menu.objects.get(id=11).sushi_toppings.all()
SELECT ...(略)...
FROM sales_sushitopping
INNER JOIN sales_menu_sushi_toppings ON (...(略)...)
WHERE menu_id = 11;
models.py
class Menu(models.Model):
sushi_toppings = models.ManyToManyField(SushiTopping)
トッピングが持つMenuを取得

id トッピング
1 🐟
トッピング お品書き
🐟 🐟🦑お任せ2貫
🦑 🐟🦑お任せ2貫

トッピング
 中間テーブル

id トッピング お品書き
1 🐟 🐟
1 🐟 🐟🦑お任せ2貫
SushiTopping.objects.get(id=1).menu_set.all()
SELECT ...(略)...
FROM
sales_menu
INNER JOIN
sales_menu_sushi_toppings
ON (...(略)...)
WHERE
menu_sushi_toppings.sushitopping_id = 1;
M2Mを逆から参照:関連しているテーブル名_set.all()

ManyToManyまとめ

● ManyToMany(M2M)は中間テーブルが作られる

● M2Mはどちら側からも多で取得

● 仕組みが分かれば怖くない!

大将:「サーモンの売上げだけだしてくれよ」

やりたいこと:親モデルの項目で絞り込み

id name
2 🐟サーモン
売上げ日
 お品書き_id

2019/05/16
 2

2019/05/18
 2

2019/05/17
 3

menu

売上げ日 お品書き
2019/05/16 2
2019/05/18 2

Sale

Sale.objects.filter(menu__name='サーモン')
親子関係の別モデルで絞り込み:FK__field_name=value

→アンダースコア2つで辿れる

SELECT ...(略)... FROM "sales_sale"
INNER JOIN "sales_menu" ON (略)
WHERE sales_menu.name = 'サーモン';
id | sales_date | menu_id | id | name | price |
-----+------------------------+---------+----+----------+-------+-
17 | 2019-03-28 06:33:02+00 | 2 | 2 | サーモン | 4335 |
318 | 2019-01-20 16:46:40+00 | 2 | 2 | サーモン | 4335 |
おさらい
● 親子関係

○ 子 → 親 model.ForeignKey 

○ 親 → 子 model.親のモデル名_set.all()

● ManyToMany(M2M)

○ 宣言してる方 → してない方: model.ManyToManyField.all()

○ 宣言してない方 → してる方: model.相手のモデル名_set.all()

● 別モデルの項目で絞り込み

○ [親子モデル]__[field_name]=value 

○ Sale.objects.filter(menu__name= 'サーモン')

大将:「これで売上げの管理も完璧だな」

目次

第一部:データを取得しよう! 🏅

第二部:親や子のモデルへのアクセス 🏅

第三部:select_relatedとprefetch_related 🍣

第四部:集計/集約

第五部:JsonFieldへのクエリ発行(※PostgreSQL限定)

大将:「売上げの一覧が重すぎる」

for s in Sale.objects.all():
s.menu.name
クエリを確認

うわわあああああああああああ

(0.014) SELECT "sales_sale"."id", "sales_sale"."sales_date", "sales_sale"."menu_id" FROM "sales_sale"; 

(0.002) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 9; 

(0.002) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 14; 

(0.002) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 3; 

(0.002) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 7; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 8; 

(0.002) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 3; 

(0.002) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 1; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 14; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 14; 

(0.010) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 13; 

(1.009) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 8; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 13; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 7; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 10; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 11; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 13; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 2; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 5; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 11; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 8; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 11; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 3; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 10; 

(0.002) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 13; 

(0.001) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 7; 

(0.002) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu" WHERE "sales_menu"."id" = 11; 

● ドットで感覚的にアクセスできる

● 実はJoinしていない

● Python側で親のオブジェクトを1件取得している



親へのアクセス時
 思い出してみましょう

for s in Sale.objects.select_related("menu").all():
s.menu.name
select_related:

SELECT
…(略) …
FROM
sales_sale
INNER JOIN
sales_menu
ON (sales_sale.menu_id = sales_menu.id);
大将:「類似確認してる?お品書きのトッピングが出すとこ
ろも無駄なクエリがでてなイカ?」

for m in Menu.objects.all():
for st in m.sushi_toppings.all():
st.name
(0.003) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu";
(0.003) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 1;
(0.004) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 2;
(0.003) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 3;
(0.002) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 4;
(0.002) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 5;
(0.002) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 6;
やっぱり!

浅はかな僕は何も考えず同じ事をする

for m in Menu.objects.select_related(‘sushi_toppings’).all():
for st in m.sushi_toppings.all():
st.name
django.core.exceptions.FieldError: Invalid field
name(s) given in select_related: 'sushi_toppings'.
Choices are: (none)
回答:prefetch_related

prefetch_related は、各リレーションシップに対して別々に検索を行い、Python で '結合’
を行います。これにより、select_related で可能な外部キーおよび一対一のリレーション
シップだけでなく、多対多および多対一のオブジェクトも事前に読み込んでおけるように
なります。

https://docs.djangoproject.com/ja/2.2/ref/models/querysets/#prefetch-related
for m in Menu.objects.prefetch_related('sushi_toppings').all():
for st in m.sushi_toppings.all():
st.name
SQLは2本になった!

SELECT ...(略)... FROM "sales_menu";
SELECT
...(略)...(sales_menu_sushi_toppings.menu_id) AS _prefetch_related_val_menu_id,
ON (
"sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id"
)
WHERE
sales_menu_sushi_toppings.menu_id IN(1, ...(略)... 15);
取得結果

_prefetch_related_val_menu_id | id | name
-------------------------------+----+------------------
14 | 8 | アナゴ
14 | 1 | トロ
14 | 2 | サーモン
2 | 2 | サーモン
多対多の中間テーブル

id | name | price
----+-----------------+---------
2 | サーモン | 4335
14 | 王道3貫 | 2000
15 | 裏メニュー | 5000000
Menu

取得結果

_prefetch_related_val_menu_id | id | name
-------------------------------+----+------------------
14 | 8 | アナゴ
14 | 1 | トロ
14 | 2 | サーモン
2 | 2 | サーモン
多対多の中間テーブル

id | name | price
----+-----------------+---------
2 | サーモン | 4335
14 | 王道3貫 | 2000
15 | 裏メニュー | 5000000
Menu

取得結果

_prefetch_related_val_menu_id | id | name
-------------------------------+----+------------------
14 | 8 | アナゴ
14 | 1 | トロ
14 | 2 | サーモン
2 | 2 | サーモン
多対多の中間テーブル

id | name | price
----+-----------------+---------
2 | サーモン | 4335
14 | 王道3貫 | 2000
15 | 裏メニュー | 5000000
Menu

ここの取得はSQLではなく
Pythonがおこなっている! 

prefetch_relatedとは
● 多対多の相手のモデルをprefetch

● 実際にはPythonが複数のクエリの結果を結合している

● SQLだけでは完結していない

● その辺を意識しなくても利用することができる

まとめ

・世界は残酷なのでSQLがいっぱい吐かれていてもそれが見えない



・select_related:SQLの世界で対1(親など)のオブジェクトをJoin

・prefetch_related: 別々のクエリを先に取得してPythonが結合



・裏側がどう動いていても感覚的にデータの取得は出来る!

大将:「良い感じになったね」

休憩

今日の正装についての簡単な説明をします。(今日一番言いたいこと)

  ∧_∧   / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 

 ( ・∀・)<常に向上するって意味でマーベルの人も使っているとても良い言葉なんだ! 

 ( 建前 )  \_______________ 

 | | |

__(__)_)______________ 

 ( _)_)

 | | |

 ( 本音 )   / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 

 ( 。A。)< 某ライブアイドルグループの最新アルバムだよ!みんな聴いてね! 

  ∨ ̄∨     \_______________ 

エクセルシオールとは

目次

第一部:データを取得しよう! 🏅

第二部:親や子のモデルへのアクセス 🏅

第三部:select_relatedとprefetch_related 🏅

第四部:集計/集約 🍣

第五部:JsonFieldへのクエリ発行(※PostgreSQL限定)

大将:「総売上っていくらなの?」

Aggregate:指定した項目で集約する

Sale.objects.all().aggregate(Sum("menu__price"))
SELECT
SUM(sales_menu.price) AS menu__price__sum
FROM
sales_sale
INNER JOIN sales_menu
ON (sales_sale.menu_id = sales_menu.id);
menu__price__sum
------------------
3471964
Aggregate(集計)のイメージ
売上げ日 お品書き 価格
昨日 カッパ巻き 1000
一昨日 コース 1200
3日前 かんぴょう巻き 2000
総売上
4200
Sale.objects.all().aggregate(Sum("menu__price"))
大将:「お品書きが売れた回数知りたい」

Djangoの集約に対する一般人僕の認識

はっきり言って分かりにくい
Django初心者が真っ先に躓くポイント、今でもよく分かりません。
SQLを書いた方がまし
O/RMが叩かれる原因
主人がO/Rマッパーに転がされて 1年が過ぎました
ハム
エッグ
スパム
もうO/RMに疲れたよ・・・・

class Menu(models.Model):
・・・
@property
def sales_count(self):
return self.sale_set.all().count()
m = Menu.objects.get(id=1)
m.sales_count # ->9999
大将:「SQLの世界でなんとかしてよ」

Annotate:オブジェクト単位に集約

from django.db.models import Count
Menu.objects.annotate(Count('sale'))
id | name | price | features | sale__count
----+----------------------+---------+----------+-------------
11 | カリフォルニアロール | 4844 | | 61
9 | タマゴヤキ | 4414 | | 69
15 | 裏メニュー | 5000000 | | 0
3 | 炙りサーモン | 7326 | | 66
5 | マグロ | 3953 | | 78
SQLを見てみると・・・

SELECT
COUNT("sales_sale"."id") AS "sale__count"
FROM
sales_menu
LEFT OUTER JOIN
sales_sale
ON (sales_menu.id = sales_sale.menu_id)
GROUP BY
sales_menu.id,
sales_menu.name,
sales_menu.price;
Menu.objects.annotate(Count('sale'))
SQLを見てみると・・・

SELECT
COUNT("sales_sale"."id") AS "sale__count"
FROM
sales_menu
LEFT OUTER JOIN
sales_sale
ON (sales_menu.id = sales_sale.menu_id)
GROUP BY
sales_menu.id,
sales_menu.name,
sales_menu.price;
Menu.objects.annotate(Count('sale'))
←子のSaleモデルのIDの数を数える 

←Menu単位にグルーピングする 

Menu単位にgroup_byってどこでわかる?

よく分からないので公式を見ます

Per-object summaries can be generated using the annotate() clause. When an annotate()
clause is specified, each object in the QuerySet will be annotated with the specified values.
The syntax for these annotations is identical to that used for the aggregate() clause. Each
argument to annotate() describes an aggregate that is to be calculated.
https://docs.djangoproject.com/ja/2.2/topics/db/aggregation/#generating-aggregat
es-for-each-item-in-a-queryset
よく分からないのでGoogle先生に翻訳してもらいました

annotate()句を使用して、オブジェクトごとのサマリーを生成できます。 annotate()
句が指定されると、QuerySet内の各オブジェクトは指定された値で注釈が付けら
れます。
これらの注釈の構文は、aggregate()句に使用されているものと同じです。
annotate()の各引数は、計算される集計を表します。
https://docs.djangoproject.com/ja/2.2/topics/db/aggregation/#generating-aggregat
es-for-each-item-in-a-queryset
ん?

annotate()句を使用して、オブジェクトごとのサマリーを生成できます。 

https://docs.djangoproject.com/ja/2.2/topics/db/aggregation/#generating-aggregat
es-for-each-item-in-a-queryset
つまりは

オブジェクト毎というのはMenuのレコード毎か!

Menu.objects.annotate(Count('sale'))
(再掲)Aggregate(集計)のイメージ
売上げ日 お品書き 価格
昨日 カッパ巻き 1000
一昨日 コース 1200
3日前 かんぴょう巻き 2000
総売上
4200
Sale.objects.all().aggregate(Sum("menu__price"))
Annotate(注釈)のイメージ
売上げ
日
お品書き 価格 sale__count
昨日 カッパ巻き 1000 100
一昨日 コース 1200 111
3日前 かんぴょう巻
き
2000 120
Sale.objects.all().aggregate(Sum("menu__price"))
Annotate(注釈)のイメージ
売上げ日 お品書き 価格 sale__count
昨日 カッパ巻き 1000 100
一昨日 コース 1200 111
3日前 かんぴょう
巻き
2000 120
Sale.objects.all().aggregate(Sum("menu__price"))
レコードの枚数はそのままで、CountやSUMといった注釈情報を加えることが出来
る!

分かった!(気がする)

じゃあ違う単位でAnnotateするには?
集約の単位を変える: values().annotate()
Sale.objects.all().values("menu").annotate(Count('menu'))
SELECT
sales_sale.menu_id,
COUNT(sales_sale.menu_id) AS menu__count
FROM
sales_sale
GROUP BY
sales_sale.menu_id;
menu_id | menu__count
---------+-------------
4 | 69
まとめ

● Aggregate

○ クエリセット全体の集計を取る、結果は1つになる

○ Sale.objects.all().aggregate(Sum("menu__price")) 

○ 総額だけ取れる

● Annotate

○ オブジェクト単位で集約結果などの”注釈情報”を付与する

○ Menu.objects.annotate(Count('sale')) 

○ Menu毎に売上げ回数がセットされる

大将:「60回以上売れたお品書きだけだ
してよ」

注釈のFieldで絞り込み:filter(XX=XX)

Menu.objects.annotate(Count('sale')).filter(sale__count__gte=60)
SELECT
COUNT(sales_sale.id) AS sale__count
FROM
sales_menu
LEFT OUTER JOIN sales_sale ON (sales_menu.id =
sales_sale.menu_id)
GROUP BY sales_menu.id
HAVING COUNT(sales_sale.id) >= 60;
id | name | price | features | sale__count
----+----------------------+-------+----------+-------------
11 | カリフォルニアロール | 4844 | | 61
9 | タマゴヤキ | 4414 | | 69
すごい直感的!

まとめ

● Having

○ Annotateで取得したエリアでfilterすればよい

○ Menu.objects.annotate(Count('sale')).filter(sale__count__gte=60)

○ 60回以上売れたMenuだけとれる

大将:「集計も集約も完璧じゃなイ
カ・・」

winodow関数について

表題にはwindow関数までと書きましたが時間がないので割愛します。。

やり方は公式を見れば分かると思います :bow:



https://docs.djangoproject.com/en/2.2/ref/models/expressions/#window-functions

休憩:Django ShellでいちいちModelのimportだるい

shell_plusってライブラリを入れるとDjango shellがすごく使いやすくなるのでオススメ!
PycharmのPythonConcsoleで動かしたいときは拙ブログにやり方が載ってるよ!
http://farewell-work.hatenablog.com/entry/2019/04/09/184141
休憩:Django ShellでModelのimportつらい

shell_plusというライブラリ

● モデルのインポート

● settingsのインポート

等々をやってくれるのでオススメ!

PycharmのPythonConsoleで動かしたいときは拙ブログにやり方が載ってるよ!

http://farewell-work.hatenablog.com/entry/2019/04/09/184141

目次

第一部:データを取得しよう! 🏅

第二部:親や子のモデルへのアクセス 🏅

第三部:select_relatedとprefetch_related 🏅

第四部:集計/集約 🏅

第五部:JsonFieldへのクエリ発行(※PostgreSQL限定) 🍣

大将:「お品書きに味:うまい , とてもうまい, 
セール:賞味期限切れセール実施中! みた
いに好きなこと入れたいんだけど味に限らずど
んな項目でも自由に入れられるようにして欲し
い」
Jsonフィールドへのクエリ発行

models.py

from django.contrib.postgres.fields import JSONField
class Menu(models.Model):
...
features = JSONField(blank=True, null=True)
レコードにはJsonが入る

id | name | price | features
----+------+-------+-----------------------
1 | トロ | 3063 | {"taste": "うまい!"}
JSONフィールドの取り方:__key="value"

Menu.objects.filter(features__taste="うまい!")
SELECT
…(略)...
FROM
sales_menu
WHERE
(sales_menu.features - > 'teste') = '"u3046u307eu3044uff01"';
id | name | price | features
----+------+-------+-----------------------
1 | トロ | 3063 | {"taste": "うまい!"}
大将:「これが最後の依頼だ自由入力の値も一
部引っかかった値での検索もよろしく」

敗北宣言:SQLを書かざるを得なかった・・・

with connection.cursor() as cursor:
sql = "select * from sales_menu where features ->> %s like %s"
cursor.execute(sql, ["taste", "%うまい%"])
results = cursor.fetchall()
まとめ

● Jsonフィールドに対してもクエリ発行できる

○ Model.objects.filter(json_field__key=value) 

○ like検索はできなかった・・

大将:「色々ありがとう!おかげでお店の評価
も上がりそうだ」

総まとめ

● 第一部:データを取得しよう! 🏅 

○ filterやexcludeで簡単にwhere句が使える 

● 第二部:親や子のモデルへのアクセス 🏅

○ _setやドットで簡単に親子どちら側からもアクセスできる! 

● 第三部:select_relatedとprefetch_related 🏅

○ これを指定してあげればパフォーマンスが一挙に改善するかも! 

● 第四部:集計/集約 🏅

○ Annotateについてなんか分かった気がする! 

● 第五部:JsonFieldへのクエリ発行(※PostgreSQL限定) 🏅

○ like検索は出来なかったけど普通に取得は出来た!  

感想
● Djangoのクエリは結構感覚的!

● 逆に感覚的すぎてよくわからない

● でも深追いすると結構分かった気がする

● 今回は登壇することで勉強になった

🍣
Excelsior!
常に向上を!


More Related Content

What's hot

Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep DiveMartijn Dashorst
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 formsEyal Vardi
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 Yong Joon Moon
 
Flask Introduction - Python Meetup
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python MeetupAreski Belaid
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱PgDay.Seoul
 
Django admin site 커스텀하여 적극적으로 활용하기
Django admin site 커스텀하여 적극적으로 활용하기Django admin site 커스텀하여 적극적으로 활용하기
Django admin site 커스텀하여 적극적으로 활용하기영우 박
 
12 tips on Django Best Practices
12 tips on Django Best Practices12 tips on Django Best Practices
12 tips on Django Best PracticesDavid Arcos
 
Web development with django - Basics Presentation
Web development with django - Basics PresentationWeb development with django - Basics Presentation
Web development with django - Basics PresentationShrinath Shenoy
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 
Django - Python MVC Framework
Django - Python MVC FrameworkDjango - Python MVC Framework
Django - Python MVC FrameworkBala Kumar
 
Django Architecture Introduction
Django Architecture IntroductionDjango Architecture Introduction
Django Architecture IntroductionHaiqi Chen
 
Intro To Mongo Db
Intro To Mongo DbIntro To Mongo Db
Intro To Mongo Dbchriskite
 
Helpful logging with python
Helpful logging with pythonHelpful logging with python
Helpful logging with pythonroskakori
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for BeginnersJason Davies
 

What's hot (20)

Django Best Practices
Django Best PracticesDjango Best Practices
Django Best Practices
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
Flask Basics
Flask BasicsFlask Basics
Flask Basics
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep Dive
 
Rest api with Python
Rest api with PythonRest api with Python
Rest api with Python
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 forms
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
 
Flask Introduction - Python Meetup
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python Meetup
 
PostgreSQL Replication Tutorial
PostgreSQL Replication TutorialPostgreSQL Replication Tutorial
PostgreSQL Replication Tutorial
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
 
Spring Core
Spring CoreSpring Core
Spring Core
 
Django admin site 커스텀하여 적극적으로 활용하기
Django admin site 커스텀하여 적극적으로 활용하기Django admin site 커스텀하여 적극적으로 활용하기
Django admin site 커스텀하여 적극적으로 활용하기
 
12 tips on Django Best Practices
12 tips on Django Best Practices12 tips on Django Best Practices
12 tips on Django Best Practices
 
Web development with django - Basics Presentation
Web development with django - Basics PresentationWeb development with django - Basics Presentation
Web development with django - Basics Presentation
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
Django - Python MVC Framework
Django - Python MVC FrameworkDjango - Python MVC Framework
Django - Python MVC Framework
 
Django Architecture Introduction
Django Architecture IntroductionDjango Architecture Introduction
Django Architecture Introduction
 
Intro To Mongo Db
Intro To Mongo DbIntro To Mongo Db
Intro To Mongo Db
 
Helpful logging with python
Helpful logging with pythonHelpful logging with python
Helpful logging with python
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
 

Similar to Django congress jp 2019 make query great again! (slide share)

Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackkimukou_26 Kimukou
 
Enumはデキる子 ~ case .Success(let value): ~
 Enumはデキる子 ~ case .Success(let value): ~ Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~Takaaki Tanaka
 
20120421中国gtug
20120421中国gtug20120421中国gtug
20120421中国gtugYusuke Sato
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
タダで始めるテストファースト入門 ~ C# Express + NUnit
タダで始めるテストファースト入門 ~ C# Express + NUnitタダで始めるテストファースト入門 ~ C# Express + NUnit
タダで始めるテストファースト入門 ~ C# Express + NUnitYasuhiko Yamamoto
 
はじめてのPython
はじめてのPythonはじめてのPython
はじめてのPythonKatsumi Honda
 
サーバ性能改善事例
サーバ性能改善事例サーバ性能改善事例
サーバ性能改善事例KLab Inc. / Tech
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
15分でざっくり分かるScala入門
15分でざっくり分かるScala入門15分でざっくり分かるScala入門
15分でざっくり分かるScala入門SatoYu1ro
 
JavaScriptおよびXPages Vote技術解説
JavaScriptおよびXPages Vote技術解説JavaScriptおよびXPages Vote技術解説
JavaScriptおよびXPages Vote技術解説賢次 海老原
 
前回のCasual Talkでいただいたご要望に対する進捗状況
前回のCasual Talkでいただいたご要望に対する進捗状況前回のCasual Talkでいただいたご要望に対する進捗状況
前回のCasual Talkでいただいたご要望に対する進捗状況JubatusOfficial
 
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~leverages_event
 
XP寺子屋第9回「シンプル・プログラミング」
XP寺子屋第9回「シンプル・プログラミング」XP寺子屋第9回「シンプル・プログラミング」
XP寺子屋第9回「シンプル・プログラミング」takepu
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2Nishida Kansuke
 
Introduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshellIntroduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshellbitter_fox
 
WordBench Kobe jQueryどうでしょう
WordBench Kobe jQueryどうでしょうWordBench Kobe jQueryどうでしょう
WordBench Kobe jQueryどうでしょうHishikawa Takuro
 
Django Rest Frameworkでお手軽にREST APIを作る
Django Rest Frameworkでお手軽にREST APIを作るDjango Rest Frameworkでお手軽にREST APIを作る
Django Rest Frameworkでお手軽にREST APIを作るMatsuo Keita
 

Similar to Django congress jp 2019 make query great again! (slide share) (20)

Ruby test double
Ruby test doubleRuby test double
Ruby test double
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hack
 
Enumはデキる子 ~ case .Success(let value): ~
 Enumはデキる子 ~ case .Success(let value): ~ Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~
 
20120421中国gtug
20120421中国gtug20120421中国gtug
20120421中国gtug
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
Teclab3
Teclab3Teclab3
Teclab3
 
タダで始めるテストファースト入門 ~ C# Express + NUnit
タダで始めるテストファースト入門 ~ C# Express + NUnitタダで始めるテストファースト入門 ~ C# Express + NUnit
タダで始めるテストファースト入門 ~ C# Express + NUnit
 
はじめてのPython
はじめてのPythonはじめてのPython
はじめてのPython
 
サーバ性能改善事例
サーバ性能改善事例サーバ性能改善事例
サーバ性能改善事例
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
15分でざっくり分かるScala入門
15分でざっくり分かるScala入門15分でざっくり分かるScala入門
15分でざっくり分かるScala入門
 
JavaScriptおよびXPages Vote技術解説
JavaScriptおよびXPages Vote技術解説JavaScriptおよびXPages Vote技術解説
JavaScriptおよびXPages Vote技術解説
 
前回のCasual Talkでいただいたご要望に対する進捗状況
前回のCasual Talkでいただいたご要望に対する進捗状況前回のCasual Talkでいただいたご要望に対する進捗状況
前回のCasual Talkでいただいたご要望に対する進捗状況
 
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
 
XP寺子屋第9回「シンプル・プログラミング」
XP寺子屋第9回「シンプル・プログラミング」XP寺子屋第9回「シンプル・プログラミング」
XP寺子屋第9回「シンプル・プログラミング」
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2
 
Introduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshellIntroduction to JShell #JavaDayTokyo #jdt_jshell
Introduction to JShell #JavaDayTokyo #jdt_jshell
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
WordBench Kobe jQueryどうでしょう
WordBench Kobe jQueryどうでしょうWordBench Kobe jQueryどうでしょう
WordBench Kobe jQueryどうでしょう
 
Django Rest Frameworkでお手軽にREST APIを作る
Django Rest Frameworkでお手軽にREST APIを作るDjango Rest Frameworkでお手軽にREST APIを作る
Django Rest Frameworkでお手軽にREST APIを作る
 

Recently uploaded

[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 

Recently uploaded (9)

[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 

Django congress jp 2019 make query great again! (slide share)