pythonのDjangoフレームワーク(orm単表クエリー、orm多表クエリー、集約クエリー、パケットクエリー、Fクエリー、Qクエリー、トランザクション、Django ORM実行生SQL)

43533 ワード

12.329 orm単一テーブルクエリー
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()