pythonのDjangoフレームワーク(orm単表クエリー、orm多表クエリー、集約クエリー、パケットクエリー、Fクエリー、Qクエリー、トランザクション、Django ORM実行生SQL)
43533 ワード
12.329 orm単一テーブルクエリー
12.3210 ormマルチテーブルクエリー(方式2)
ForeignKey操作:ブックテーブル(Bookテーブル)外部キー関連出版社テーブル(Publisherテーブル)
順方向検索:
逆検索:
ManyToManyField:(使用方法2:ManyToManyFieldによる3枚目のテーブルの自動作成)
models:
class RelatedManager:「関連マネージャ」は、1対以上の関連コンテキストで使用されるマネージャです.
外部キー関係の逆クエリー、多対多関連関係、簡単には「.」後ろのオブジェクトが複数存在する場合は以下の方法を使用できます.
create():新しいオブジェクトを作成し、オブジェクトを保存し、関連オブジェクトセットに追加し、新しく作成したオブジェクトを返します.
add():指定したmodelオブジェクトまたはオブジェクトidを関連オブジェクトセットに追加する
set():modelオブジェクトの関連オブジェクトを更新します.
remove():実行されたモデルオブジェクトを関連オブジェクトセットから削除します.
clear():関連オブジェクトセットからすべてのオブジェクトを除去します.
注意:ForeignKeyオブジェクトの場合、clear()メソッドとremove()メソッドはnull=Trueの場合にのみ存在します.
all():
12.3211集約クエリー
Aggregate()は、いくつかのキー値ペアを含む辞書を返すQuerySetの終了文です.
キーの名前は集約値の識別子であり、値は計算された集約値です.キーの名前は、フィールドと集約関数の名前に基づいて自動的に生成されます.
12.3212グループクエリー
単表照会グループ:部門グループによって平均賃金を求める
ormクエリー:
連表照会のグループ化:部門グループによって平均給与を求める
ORMクエリー:
著者、図書、出版社の表関係:
例:
12.3213 Fクエリー
F()のインスタンスは、同じモデルインスタンスの2つの異なるフィールドの値を比較するために、クエリーでフィールドを参照することができる.
商品表構造:
例:
12.3214 Qクエリー
filter()などのメソッドにおけるキーワードパラメータクエリは,ともに「AND」を行う.より複雑なクエリ(OR文など)を実行する必要がある場合は、Qオブジェクトを使用します.
例:
クエリ関数は、Qオブジェクトとキーワードパラメータを混在させることができます.クエリー関数に提供されるすべてのパラメータ(キーワードパラメータまたはQオブジェクト)はANDとともに使用されます.ただし、Qオブジェクトが表示される場合は、すべてのキーワードパラメータの前にある必要があります.
12.3215取引
トランザクションを開くと、同時に成功するか、成功しないかのいずれかのsql文を含むsql文が含まれます.トランザクションは、トランザクションの原子的役割と呼ばれます.トランザクションは、いくつかの操作の複数のSQLを原子的な操作として使用し、エラーが発生すると、元の状態にロールバックし、データベース・データの整合性を保証します.
12.3216 Django ORM原生SQL実行
多くの場合、クエリー結果をモデルにマッピングする必要はありません.また、DELETE、INSERT、UPDATE操作を実行する必要があります.これらの場合、モデルレイヤを完全に回避するためにデータベースに直接アクセスできます.djangoが提供するインタフェースから直接データベース接続を取得し、pymysqlモジュールを使用するようにデータベースを操作できます.
import os
if __name__ == '__main__':
# py Django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_demo.settings")
import django
django.setup() # Django
from app01 import models
# QuerySet :
ret = models.Book.objects.all()
print(ret) # QuerySet :
ret = models.Book.objects.filter(title=" ") # QuerySet -->
# id 1
ret = models.Book.objects.filter(id__gt=1)
# id 3
ret = models.Book.objects.filter(id__lt=3)
# 2017
ret = models.Book.objects.filter(publisher_date__year=2017)
# 2017
ret = models.Book.objects.filter(publisher_date__year__gt=2017)
# ' '
ret = models.Book.objects.filter(title__contains=" ")
# ' ' 2018
ret = models.Book.objects.filter(title__contains=" ", publisher_date__year=2018)
# get 。
# , : ,
ret = models.Book.objects.get(id=10)
print(ret) #
# filter QuerySet
ret = models.Book.objects.filter(id=10)
print(ret) #[]
# ,
ret = models.Book.objects.exclude(id__in=[1,3,4])
print(ret)
#
ret = models.Book.objects.all().order_by("price") # QuerySet : price
ret = models.Book.objects.all().order_by("-price")
#
ret = models.Book.objects.all().order_by("price").reverse()
# # QuerySet :
ret = models.Book.objects.all().order_by("publisher_date").reverse().values("title")
# QuerySet:
#values() ,
ret = models.Book.objects.filter(publisher_date__year=2018).values("title", "publisher_date")
print(ret) # QuerySet :
#values_list() ,
ret = models.Book.objects.filter(publisher_date__year=2018).values_list("title", "publisher_date") # QuerySet :
#
ret = models.Book.objects.all().values("publisher__name").distinct()
print(ret) # QuerySet : ,
#
# count
ret = models.Book.objects.all().count() # :
#
#first() last()
ret = models.Book.objects.all().first() #
#get()
ret = models.Book.objects.get(id=1) # ,
#
#
ret = models.Book.objects.all().exists() # :
12.3210 ormマルチテーブルクエリー(方式2)
ForeignKey操作:ブックテーブル(Bookテーブル)外部キー関連出版社テーブル(Publisherテーブル)
順方向検索:
1. ( )
book_obj = models.Book.objects.first() #
print(book_obj.publisher) #
print(book_obj.publisher.name) #
2. ( )
print(models.Book.objects.values_list("publisher__name"))
逆検索:
1. ( )
publisher_obj = models.Publisher.objects.first() #
books = publisher_obj.book_set.all() #
titles = books.values_list("title") #
# related_name="books"
#publisher= models.ForeignKey(to="Publisher", related_name="books")
publisher_obj = models.Publisher.objects.first()
ret = publisher_obj.books.all()
print(ret)#, ]>
2. ( )
ret = models.Publisher.objects.filter(id=1).values_list("book__title")
print(ret)#
titles = models.Publisher.objects.values_list("book__title")
print(titles)#
# related_query_name="books" related_name="books"( , related_query_name )
titles = models.Publisher.objects.filter(id=1).values_list("books__title")
#
titles = models.Publisher.objects.filter(id=1).values("books__title")
#
ManyToManyField:(使用方法2:ManyToManyFieldによる3枚目のテーブルの自動作成)
models:
class Book(models.Model):
title = models.CharField(max_length=32)
publish_date = models.DateField(auto_now_add=True)
price = models.DecimalField(max_digits=5, decimal_places=2)
memo = models.TextField(null=True)
# , publish
publisher = models.ForeignKey(to="Publisher", )
# author
author = models.ManyToManyField(to="Author")
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
phone = models.CharField(max_length=11)
detail = models.OneToOneField(to="AuthorDetail")
class RelatedManager:「関連マネージャ」は、1対以上の関連コンテキストで使用されるマネージャです.
外部キー関係の逆クエリー、多対多関連関係、簡単には「.」後ろのオブジェクトが複数存在する場合は以下の方法を使用できます.
create():新しいオブジェクトを作成し、オブジェクトを保存し、関連オブジェクトセットに追加し、新しく作成したオブジェクトを返します.
#models.Book.objects.first().author class RelatedManager , .create author
1. author
ret = models.Book.objects.first().author.create(name=" ",age=16,phone="18012xxxx",detail_id=4)
# :1. ,2.
ret = models.Book.objects.first().author.all().values("id")
print(ret)#
2. book
import datetime
models.Author.objects.first().book_set.create(title=" ", publish_date=datetime.date.today())
add():指定したmodelオブジェクトまたはオブジェクトidを関連オブジェクトセットに追加する
#
author_objs = models.Author.objects.filter(id__lt=3)
models.Book.objects.first().author.add(*author_objs)
# id
models.Book.objects.first().author.add(*[1, 2])
models.Book.objects.first().author.add(1)
# id
ret = models.Book.objects.first().author.all().values("id")
print(ret)#
set():modelオブジェクトの関連オブジェクトを更新します.
ret=models.Book.objects.first().author.set([2, 3])# , book id=2 3
ret = models.Book.objects.first().author.all()
print(ret)#, , ]>
ret = models.Book.objects.first().author.all().values("id")
print(ret)#
remove():実行されたモデルオブジェクトを関連オブジェクトセットから削除します.
models.Book.objects.first().author.remove(3)# , id=3 #
ret = models.Book.objects.first().author.all().values("id")
print(ret) #
clear():関連オブジェクトセットからすべてのオブジェクトを除去します.
#
models.Book.objects.first().author.clear()
ret = models.Book.objects.first().author.all().values("id")
print(ret)#
注意:ForeignKeyオブジェクトの場合、clear()メソッドとremove()メソッドはnull=Trueの場合にのみ存在します.
all():
ret = models.Book.objects.first().author.all()#
print(ret) #
12.3211集約クエリー
Aggregate()は、いくつかのキー値ペアを含む辞書を返すQuerySetの終了文です.
キーの名前は集約値の識別子であり、値は計算された集約値です.キーの名前は、フィールドと集約関数の名前に基づいて自動的に生成されます.
from django.db.models import Avg, Sum, Max, Min, Count
models.Book.objects.all().aggregate(Avg("price"))
#{'price__avg': 13.233333}
ret = models.Book.objects.aggregate(Sum("price"))
#{'price__sum': Decimal('13.10')
ret = models.Book.objects.aggregate(total_price=Sum("price"))
#{'total_price': Decimal('13.10')}
ret = models.Book.objects.aggregate(avg_price=Avg("price"), max_price=Max("price"), min_price=Min("price"))
#{'avg_price': 4.366667, 'max_price': Decimal('12.00'), 'min_price': Decimal('0.10')}
12.3212グループクエリー
単表照会グループ:部門グループによって平均賃金を求める
select dept,AVG(salary) from employee group by dept;
ormクエリー:
from django.db.models import Avg
models.Employee.objects.values("dept").annotate(avg=Avg("salary")
#
models.Employee.objects.values("dept").annotate(avg=Avg("salary").values('dept', "avg")
#
連表照会のグループ化:部門グループによって平均給与を求める
select dept.name,AVG(salary) from employee inner join dept on (employee.dept_id=dept.id) group by dept_id;
ORMクエリー:
from django.db.models import Avg
models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")
models.Employee.objects.values("dept__name").annotate(avg=Avg("salary"))
#
models.Employee.objects.values("dept__name").annotate(avg=Avg("salary")).values('dept', "avg")
#
models.Employee.objects.values("dept__name")
#
著者、図書、出版社の表関係:
from django.db import models
#
class Publisher(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
#
class Book(models.Model):
title = models.CharField(max_length=32)
publish_date = models.DateField(auto_now_add=True)
price = models.DecimalField(max_digits=5, decimal_places=2)
# , publish
publisher = models.ForeignKey(to="Publisher")
# author
author = models.ManyToManyField(to="Author")
#
class Author(models.Model):
name = models.CharField(max_length=32)
例:
1.
(1):ret = models.Book.objects.annotate(autor_num=Count("author")).values("title", "autor_num")
#
(2):book_list = models.Book.objects.all().annotate(author_num=Count("author"))
print(book_list) #, , ]>
for obj in book_list:
print(obj.author_num)#0 1 1
2.
(1):ret = models.Publisher.objects.annotate(min_price=Min("book__price")).values("name", "min_price")
#
{'name': ' ', 'min_price': None}]>
(2):ret=models.Book.objects.values("publisher__name").annotate(min_price=Min("price"))
#
(3):publisher_list = models.Publisher.objects.annotate(min_price=Min("book__price"))
print(publisher_list)
#, , ]>
for obj in publisher_list:
print(obj.min_price)#0.10 12.00 None
3.
models.Book.objects.annotate(author_num=Count("author")).filter(author_num__gt=1)#
4. QuerySet
models.Book.objects.annotate(author_num=Count("author")).order_by("author_num")
#, , ]>
5.
models.Author.objects.annotate(sum_price=Sum("book__price")).values("name", "sum_price")
#
#{'name': ' ', 'sum_price': None}, {'name': ' san', 'sum_price': None}]>
12.3213 Fクエリー
F()のインスタンスは、同じモデルインスタンスの2つの異なるフィールドの値を比較するために、クエリーでフィールドを参照することができる.
商品表構造:
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=6, decimal_places=2)
#
keep = models.IntegerField()
#
sale = models.IntegerField()
def __str__(self):
return "{}:{}:{}:{}".format(self.name, self.price, self.keep, self.sale)
例:
from django.db.models import F
1.
models.Product.objects.filter(sale__gt=F("keep"))
#, ]>
2.Django F() F()
models.Product.objects.filter(sale__gt=F('keep')*2)
#]>
3. F : 50
models.Product.objects.all().update(price=F("price")+50)
4. " "
from django.db.models.functions import Concat
from django.db.models import Value
models.Product.objects.all().update(name=Concat(F("name"), Value(" ")))
12.3214 Qクエリー
filter()などのメソッドにおけるキーワードパラメータクエリは,ともに「AND」を行う.より複雑なクエリ(OR文など)を実行する必要がある場合は、Qオブジェクトを使用します.
# 100 100
models.Product.objects.filter(sale__gt=100, price__gt=100)
#, ]>
例:
from django.db.models import Q
1. 100 100
models.Product.objects.filter(Q(sale__gt=100)|Q(price__lt=100)) #|:
#, ]>
2. 100 0
models.Product.objects.filter(Q(keep=100)&~Q(sale=0)) #&: ,~:
models.Product.objects.filter(Q(kucun=100),~Q(maichu=0))
#]>
models.Product.objects.filter(Q(kucun=100)&~Q(maichu=0)).values('name')
#
models.Product.objects.filter(Q(kucun=100)&~Q(maichu=0)).values_list('name')
#
クエリ関数は、Qオブジェクトとキーワードパラメータを混在させることができます.クエリー関数に提供されるすべてのパラメータ(キーワードパラメータまたはQオブジェクト)はANDとともに使用されます.ただし、Qオブジェクトが表示される場合は、すべてのキーワードパラメータの前にある必要があります.
# , 60 100
models.Product.objects.filter(Q(keep__gt=60)|Q(price__lt=100), name__contains=" ")
#]>
12.3215取引
トランザクションを開くと、同時に成功するか、成功しないかのいずれかのsql文を含むsql文が含まれます.トランザクションは、トランザクションの原子的役割と呼ばれます.トランザクションは、いくつかの操作の複数のSQLを原子的な操作として使用し、エラーが発生すると、元の状態にロールバックし、データベース・データの整合性を保証します.
import os
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
import django
django.setup()
import datetime
from app01 import models
try:
from django.db import transaction
with transaction.atomic(): #
new_publisher = models.Publisher.objects.create(name=" ")
models.Book.objects.create(title=" ", publish_date=datetime.date.today(), publisher_id=10)
# id, ,
except Exception as e:
print(str(e))
12.3216 Django ORM原生SQL実行
多くの場合、クエリー結果をモデルにマッピングする必要はありません.また、DELETE、INSERT、UPDATE操作を実行する必要があります.これらの場合、モデルレイヤを完全に回避するためにデータベースに直接アクセスできます.djangoが提供するインタフェースから直接データベース接続を取得し、pymysqlモジュールを使用するようにデータベースを操作できます.
from django.db import connection, connections
cursor = connection.cursor() # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
ret = cursor.fetchone()