データベースとORM
17238 ワード
データベースとORM
一、データベースの構成
1 djangoのデフォルトでは、sqlite、mysql、oracle、postgresqlデータベースがサポートされています.
<1> sqlite
djangoのデフォルトではsqliteのデータベースが使用され、デフォルトではsqliteのデータベースドライバが付属しています.
エンジン名:django.db.backends.sqlite 3
<2> mysql
エンジン名:django.db.backends.mysql
2 mysqlドライバ MySQLdb(mysql python) mysqlclient MySQL PyMySQL(純pythonのmysqlドライバ) 3 djangoのプロジェクトではsqliteデータベースがデフォルトで使用され、settingsでは次のような設定があります.
データベースを変更するには、次のように変更する必要があります.
注意:
一、ORM表モデル
テーブル(モデル)の作成:
例:次の概念、フィールド、および関係を仮定します.
作者モデル:作者に名前があります.
著者詳細モデル:性別、emailアドレス、生年月日を含む詳細テーブルに著者詳細を配置し、著者詳細モデルと著者モデルの間には1対1の関係(one-to-one)(個人と彼の身分証明書の関係に似ている)があり、多くの場合、2つのテーブルに分割する必要はありません.ここでは一対一の概念を引き出すだけだ.
出版社モデル:出版社には名前、住所、所在都市、省、国、ウェブサイトがあります.
書籍モデル:書籍には本名と出版日があり、1冊の本には複数の著者がいる可能性があり、1人の著者も複数の本を書くことができるので、著者と書籍の関係は多対多の関連関係(many-to-many)であり、1冊の本は1つの出版社だけが出版すべきで、出版社と書籍は1対多の関連関係(one-to-many)であり、外部キーとも呼ばれている.
分析コード:
<1>各データモデルはdjango.db.models.Modelのサブクラスであり、親モデルには必要なすべてのデータベースとインタラクティブな方法が含まれています.データベースフィールドをきれいに定義する構文を提供します.
<2>各モデルは、単一のデータベース・テーブル(複数対の複数の関係例外で、複数の関係テーブルが生成されます)に相当し、各プロパティもこのテーブルのフィールドです.属性名は、CharFieldなどのフィールド名で、データベースのフィールドタイプ(varcharなど)に相当します.他のタイプがデータベースのどのフィールドに対応しているかに注意してください.
<3>モデル間の3つの関係:1対1、1対多、多対多.
一対一:実質は主外部キー(author_idはforeign key)の関係に基づいて、外部キーにUNIQUE=Trueの属性を加えたものである.
一対多:主外部キー関係です.(foreign key)
多対多:(ManyToManyField)3番目のテーブルを自動的に作成します(もちろん、3番目のテーブルを自分で作成することもできます:2つのforeign key)
1、ORMの増加(create,save)
**ポイントが来ました-------->**では、一対多または多対多の関係がある本の情報をどのように作成しますか?(1対多の
2、ORMの削除(delete)
私たちは表面的に1つの情報を削除しましたが、実際には3つ削除しました.私たちが削除したこの本はBook_にあるからです.authorsテーブルには、djangoのデフォルトのカスケード削除という2つの関連情報があります.
3、ROMの変更(updateとsave)
例:
注意:
<1>第2の方法ではgetを使用できない理由は、updateはQuerySetオブジェクトの方法であり、getはupdateメソッドがなくmodelオブジェクトを返し、filterは1つのQuerySetオブジェクトを返します(filterの中の条件は、name='alvin'、2つのname='alvin'の行データなど、複数の条件が一致する可能性があります).
<2>
さらに、update()メソッドは、任意の結果セット(QuerySet)に対して有効であり、これは、影響を受けるレコードの数を表す複数のレコードupdate()メソッドを同時に更新できることを意味します.
ここでupdateは整形を返すのでquery属性は使えません.オブジェクトを作成するたびに、対応するraw sqlを表示するには、settingsにログ・セクションを追加する必要があります.
4、ORMの調査(filterとvalue)
4.1クエリーAPI
4.2 QuerySetと不活性機構
不活性メカニズムとは、Publisher.objects.all()または.filter()などが、すぐにsqlを実行するのではなく、QuerySetを呼び出すときに実行されるQuerySet(クエリ結果セットオブジェクト)を返すだけです.
QuerySetの特徴:
<1>反復可能
<2>スライス可能
QuerySetの効率的な使用:
一、データベースの構成
1 djangoのデフォルトでは、sqlite、mysql、oracle、postgresqlデータベースがサポートされています.
<1> sqlite
djangoのデフォルトではsqliteのデータベースが使用され、デフォルトではsqliteのデータベースドライバが付属しています.
エンジン名:django.db.backends.sqlite 3
<2> mysql
エンジン名:django.db.backends.mysql
2 mysqlドライバ
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
データベースを変更するには、次のように変更する必要があります.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'books', #
'USER': 'root', #
'PASSWORD': '', #
'HOST': '', # , localhost
'PORT': '3306', #
}
}
注意:
NAME , mysql , sqlite db.sqlite3
USER PASSWORD 。
, Django , mysql。
, , :no module named MySQLdb
django MySQLdb, MySQLdb py3 , PyMySQL
, __init__, :
import pymysql
pymysql.install_as_MySQLdb()
!
一、ORM表モデル
テーブル(モデル)の作成:
例:次の概念、フィールド、および関係を仮定します.
作者モデル:作者に名前があります.
著者詳細モデル:性別、emailアドレス、生年月日を含む詳細テーブルに著者詳細を配置し、著者詳細モデルと著者モデルの間には1対1の関係(one-to-one)(個人と彼の身分証明書の関係に似ている)があり、多くの場合、2つのテーブルに分割する必要はありません.ここでは一対一の概念を引き出すだけだ.
出版社モデル:出版社には名前、住所、所在都市、省、国、ウェブサイトがあります.
書籍モデル:書籍には本名と出版日があり、1冊の本には複数の著者がいる可能性があり、1人の著者も複数の本を書くことができるので、著者と書籍の関係は多対多の関連関係(many-to-many)であり、1冊の本は1つの出版社だけが出版すべきで、出版社と書籍は1対多の関連関係(one-to-many)であり、外部キーとも呼ばれている.
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30, verbose_name=" ")
address = models.CharField(" ", max_length=50)
city = models.CharField(' ',max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
class Meta:
verbose_name = ' '
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class AuthorDetail(models.Model):
sex = models.BooleanField(max_length=1, choices=((0, ' '),(1, ' '),))
email = models.EmailField()
address = models.CharField(max_length=50)
birthday = models.DateField()
author = models.OneToOneField(Author)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2,default=10)
def __str__(self):
return self.title
分析コード:
<1>各データモデルはdjango.db.models.Modelのサブクラスであり、親モデルには必要なすべてのデータベースとインタラクティブな方法が含まれています.データベースフィールドをきれいに定義する構文を提供します.
<2>各モデルは、単一のデータベース・テーブル(複数対の複数の関係例外で、複数の関係テーブルが生成されます)に相当し、各プロパティもこのテーブルのフィールドです.属性名は、CharFieldなどのフィールド名で、データベースのフィールドタイプ(varcharなど)に相当します.他のタイプがデータベースのどのフィールドに対応しているかに注意してください.
<3>モデル間の3つの関係:1対1、1対多、多対多.
一対一:実質は主外部キー(author_idはforeign key)の関係に基づいて、外部キーにUNIQUE=Trueの属性を加えたものである.
一対多:主外部キー関係です.(foreign key)
多対多:(ManyToManyField)3番目のテーブルを自動的に作成します(もちろん、3番目のテーブルを自分で作成することもできます:2つのforeign key)
1、ORMの増加(create,save)
from app01.models import *
#create : Author.objects.create(name='Alvin')
#create : Author.objects.create(**{"name":"alex"})
#save : author=Author(name="alvin")
author.save()
#save : author=Author()
author.name="alvin"
author.save()
**ポイントが来ました-------->**では、一対多または多対多の関係がある本の情報をどのように作成しますか?(1対多の
publisher
対多のauthorsのような外部キー関係のフィールドをどのように処理するか)# (ForeignKey):
# : , publish, publish_id,
# :
Book.objects.create(title='php',
publisher_id=2, # 2 book Publisher id=2
publication_date='2017-7-7',
price=99)
# :
# <1> Publisher :
pub_obj=Publisher(name=' ',address=' ',city=' ',
state_province=' ',country='China',website='http://www.hbu.com')
OR pub_obj=Publisher.objects.get(id=1)
# <2> publisher_id=2 publisher=pub_obj
Book.objects.create(title='php',
publisher=pub_obj, # **_id 。
publication_date='2017-7-7',
price=99)
# (ManyToManyField()):
# :
# , .add 。
author1=Author.objects.get(id=1)
author2=Author.objects.filter(name='alvin')[0]
book=Book.objects.get(id=1)
book.authors.add(author1,author2)
# :
book.authors.add(*[author1,author2])
book.authors.remove(*[author1,author2])
#-------------------
# :
# , .book_set.add(*book) 。
book=models.Book.objects.filter(id__gt=1)
authors=models.Author.objects.filter(id=1)[0]
authors.book_set.add(*book)
authors.book_set.remove(*book)
#-------------------
# : , id.
book.authors.add(1) #book.authors.add(1,2) id, id
book.authors.remove(1)
authors.book_set.add(1)
authors.book_set.remove(1)
# : models.ManyToManyField() ,
# :
class Book2Author(models.Model):
author=models.ForeignKey("Author")
Book= models.ForeignKey("Book")
# :
author_obj=models.Author.objects.filter(id=2)[0]
book_obj =models.Book.objects.filter(id=3)[0]
s=models.Book2Author.objects.create(author_id=1,Book_id=2)
s.save()
s=models.Book2Author(author=author_obj,Book_id=1)
s.save()
2、ORMの削除(delete)
>>> Book.objects.filter(id=1).delete()
(3, {'app01.Book_authors': 2, 'app01.Book': 1})
私たちは表面的に1つの情報を削除しましたが、実際には3つ削除しました.私たちが削除したこの本はBook_にあるからです.authorsテーブルには、djangoのデフォルトのカスケード削除という2つの関連情報があります.
3、ROMの変更(updateとsave)
例:
author=Author.objects.get(id=5)
author.name='tenglan'
author.save()
# get(id=2)
Publister.objects.filter(id=2).update(name='American publisher')
注意:
<1>第2の方法ではgetを使用できない理由は、updateはQuerySetオブジェクトの方法であり、getはupdateメソッドがなくmodelオブジェクトを返し、filterは1つのQuerySetオブジェクトを返します(filterの中の条件は、name='alvin'、2つのname='alvin'の行データなど、複数の条件が一致する可能性があります).
<2>
“ ” , save() , 。 , 。
#---------------- update ----------------
models.Book.objects.filter(id=3).update(title="PHP")
##sql:
##UPDATE "app01_book" SET "title" = 'PHP' WHERE "app01_book"."id" = 3; args=('PHP', 3)
#--------------- save , -----------
obj=models.Book.objects.filter(id=3)[0]
obj.title="Python"
obj.save()
# SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price",
# "app01_book"."color", "app01_book"."page_num",
# "app01_book"."publisher_id" FROM "app01_book" WHERE "app01_book"."id" = 3 LIMIT 1;
#
# UPDATE "app01_book" SET "title" = 'Python', "price" = 3333, "color" = 'red', "page_num" = 556,
# "publisher_id" = 1 WHERE "app01_book"."id" = 3;
さらに、update()メソッドは、任意の結果セット(QuerySet)に対して有効であり、これは、影響を受けるレコードの数を表す複数のレコードupdate()メソッドを同時に更新できることを意味します.
ここでupdateは整形を返すのでquery属性は使えません.オブジェクトを作成するたびに、対応するraw sqlを表示するには、settingsにログ・セクションを追加する必要があります.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
4、ORMの調査(filterとvalue)
4.1クエリーAPI
# API:
# <1>filter(**kwargs):
# <2>all():
# <3>get(**kwargs): , , 。
#----------- : objects.filter.values()--------
# <4>values(*field): ValueQuerySet—— QuerySet, model ,
# <5>exclude(**kwargs):
# <6>order_by(*field):
# <7>reverse():
# <8>distinct():
# <9>values_list(*field): values() , ,values
# <10>count(): (QuerySet) 。
# <11>first():
# <12>last():
# <13>exists(): QuerySet , True, False
--------------- (__) ----------------
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # id 1 10
#
# models.Tb1.objects.filter(id__in=[11, 22, 33]) # id 11、22、33
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
#
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains
#
# models.Tb1.objects.filter(id__range=[1, 2]) # bettwen and
#
# startswith,istartswith, endswith, iendswith,
4.2 QuerySetと不活性機構
不活性メカニズムとは、Publisher.objects.all()または.filter()などが、すぐにsqlを実行するのではなく、QuerySetを呼び出すときに実行されるQuerySet(クエリ結果セットオブジェクト)を返すだけです.
QuerySetの特徴:
<1>反復可能
<2>スライス可能
#objs=models.Book.objects.all()#[obj1,obj2,ob3...]
#QuerySet:
# for obj in objs:# obj
# print("obj:",obj)
# QuerySet:
# print(objs[1])
# print(objs[1:4])
# print(objs[::-1])
QuerySetの効率的な使用:
<1>Django queryset
Django queryset (row), 。 , ‘Dave’ :person_set = Person.objects.filter(first_name="Dave")
。 person_set, , , 。 , web 。
<2> , queryset if queryset, sql. , settings LOGGING( )
obj=models.Book.objects.filter(id=3)
# for i in obj:
# print(i)
# if obj:
# print("ok")
<3>queryset cache queryset , , Django model。 (evaluation). model queryset cache , queryset, 。
obj=models.Book.objects.filter(id=3)
# for i in obj:
# print(i)
## models.Book.objects.filter(id=3).update(title="GO")
## obj_new=models.Book.objects.filter(id=3)
# for i in obj:
# print(i) #LOGGING
<4> if queryset cache, ! , exists() :
obj = Book.objects.filter(id=4)
# exists() queryset cache。
if obj.exists():
print("hello world!")
<5> queryset ,cache , 。 , queryset , 。 queryset cache, iterator() , 。
objs = Book.objects.all().iterator()
# iterator() ,
for obj in objs:
print(obj.name)
#BUT, , (next) ,
for obj in objs:
print(obj.name)
# , iterator() cache, queryset 。 iterator() , queryset 。
:
queryset cache , 。 exists() iterator() 。 , queryset cache, 。