ORM多表增删改和查询
0.1 mysql的知识
多表查询
外键 foreignkey
一对一 foreignkey+unique
被关联的表 的数据(先写,才可被关联)不可改,不可删,可以增
fk_publish 写关联的表 无所谓 常用的放这张表
publish | fk+unique(1对1) | |
---|---|---|
id | name | publish_detail_id |
1 | 20期 | 1、2不能重复 |
不常用的
publish_detail | ||
---|---|---|
id | tel | |
1 | ||
多对一
book | fk_publish | |
---|---|---|
id | title | publish_id |
1 | python | 1 |
多对多
互相建外键,不行,谁先建?✖
建第三张表 ✔
多对多 有外键,不可删23 也可以增加4 可以删除author里的1
book2authot | fk_book | fk_author |
---|---|---|
id | book_id | author_id |
1 | 1 | 2 |
2 | 1 | 3 |
3 |
author | ||
---|---|---|
id | name | 技术描述 |
1 | cls | 还行 |
很多公司不用foreign_key 了,牵一发而动全身,强制约束,导致操作变复杂
现在通过逻辑来+,建没有关系的表,inner join查。
写一段orm语句,写一段原生sql
select author.技术描述 from (select * from (从硬盘到内存) book inner join author on book.id == author.id) as t1 inner join book2author on t1.id == book2author.id;
book表,既有多对一,又有多对多,
我关联别人的,有范围
别人关联我,我随便增加 改和删不行
他连别人,所以可以随便删除,但是不可以随便添加
别人连他,所以可以随便添加,但是不可以随便删除
外键关联施,受需要有相关项
外键关联受, 必须有,不可改,不可删,可以增
1 创建模型
1.1建表
ad = models.OneToOneField(to='AuthorDetail' )
自动生成ad_id 名字
class Author():
name = models.CharField(max_length=32)
age = ..IntegerField()
authorDetail = ..OneToOneField(to = 'AuthorDetail')
class AuthorDetail(): 不常使用的字段,另建一个表,否则数据量大
telephone = ..BigInt
addr = ...Char
class Publish():
name = Char ml32
city = Char
class Book():
title = Char ml32
price = Decimal md = 5 , dp = 2
auth = Manytomany(to= 'Author')
publish = Foreign.key(to = 'Publish')
1.2 多对多的三种创建
方式1 手动创建 建三个表
联合唯一: 同时不重复
author = models.ForeignKey(to="Author")
book = models.ForeignKey(to="Book")
class Meta:
unique_together = ("author", "book")
方式2 manytomany
books = models.ManyToManyField(to="Book", related_name="authors")
方式3 manytomany 手动指定
author = models.ForeignKey(to="Author")
book = models.ForeignKey(to="Book")
class Meta:
unique_together = ("author", "book")
through 指定这个表作为第三张表 指定字段
decimal为什么精度最高?存的是字符串,所以不会改变
再存浮点型的时候,小数点,存储机制,所以会变化。。。
show create table app01_author; 查询key
UNIQUE KEY ad_id_id
(ad_id_id
), 指定了后者,名字前者
alter table app01_author drop index ad_id_id; 删除uninkey
1.3 插入
publish = models.ForeignField(to='Publish' )
自动生成publish_id 名字
方式1
publish_obj=Publish.objects.get(id=1) #拿到id为1的出版对象
book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish=publish_obj) #出版社对象作为值给publish,其实就是自动将publish字段变成publish_id,然后将publish_obj的id给取出来赋值给publish_id字段,注意你如果不是publish类的对象肯定会报错的
方式2
book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish_id=1) 属性
print(models.Book.objects.filter(id=1)[0]) #三体
print(models.Book.objects.filter(publish_id=2)[1]) #小小小小的火
publish_obj = models.Publish.objects.filter(id=1)[0] #Publish object
publish_obj = models.Publish.objects.filter(id=1)
#<QuerySet [<Publish: Publish object>]>
models.Book.objects.create(title= '人生',price=13,publish= publish_obj )
models.Book.objects.create(title= '流浪地球',price=111,publish_id= 1 )
# publish_id = 1 或者 publish = publish对象 filter()[0] 或者 get()
1.4 增(多对多)
1.3 1 第三张表
book_obj = models.Book.objects.get(id=2)
book_obj.authors (第三张表)
book_obj.authors.add(1,2)
add里面是作者对象或者是作者的id
book_obj1.auth. auth连接第三方 就是第三张表了
#增加: 添加一本书,关联两个作者
# 1.先把作者录入了 , 然后选择
# 2. 或者输入作者,去查询
book_obj = models.Book.objects.create(title='人间词话',price=23,publish_id=1)
wuqishi = models.Author.objects.get(name='伍绮诗')
liucixin = models.Author.objects.get(name='刘慈欣')
book_obj.auth.add(wuqishi,liucixin) #给第三张表add
#增的是author对象
book_obj1.auth.add(*[1,2]) #增的是author id
1.5 删
一对一更新和删除
models.Author.objects.filter(id=2).update(name= 'wang')
# models.Author.objects.filter(id=2).delete()
多对多删除
# book_obj.auth.remove(1) #author的id author对象
book_obj.authors.remove(1,3)
book_obj.authors.remove(*[1,3])
# book_obj.auth.clear() #全删对象
# book_obj.auth.set([1,2]) # 删除并且赋值
# data = {'title':'围城','price':12}
# models.Book.objects.filter(id=6).update(**data)
2 下午
2. 查
2.0 原理
基于对象的: 子查询
正向查询:
关系属性在哪张表,去关联的表去查询
往onetoone的里面去找,就是正向查询 ,否则就是反向查询
基本写法
对象= models.类.objects.filter()[0] /get()
正向查询:
用属性(.all()多 .属性 少) 对象.关联的属性.属性或者all()
反向查询:
用表名(_set : 多) (.属性 :少) 对象.前者的表名_ _ set.all() 或属性
如果没写 __ str __ 的情况下 ,写__ __ dict __显示文字
多对多的增
add里面是作者对象或者是作者的id
book_1 = models.Book.objects.filter(title='人间词话')[0]
book_1.auth.add(1,2)
2.11 一对一
正 :找作者伍绮诗的addr
author_obj = models.Author.objects.filter(name='伍绮诗')[0]
print(author_obj.authorDetail.addr) #美国
反 :找书本人间词话的出版社
book_obj3 = models.Book.objects.filter(title='人间词话')[0]
print(book_obj3.publish.city) #北京
2.12 一对多
正 :找书本人间词话的出版社
book_obj3 = models.Book.objects.filter(title='人间词话')[0]
print(book_obj3.publish.city) #北京 前三个都是属性 后三个all
反 :找出版社 新华书店 出版的图书 多
publish1 = models.Publish.objects.filter(name='人民邮电')[0]
print(publish1.book_set.all()) ##<QuerySet [<Book: 无声告白
2.13 多对多
正 : 查询book 正能量被几个作者 写出来 多
book_obj4 = models.Book.objects.filter(title='正能量')[0]
print(book_obj4,book_obj4.auth.all()) #正能量 <QuerySet
反 : 查询 作者伍绮诗 写的所有书籍 多
author_obj2 = models.Author.objects.filter(name='伍绮诗')[0]
print(author_obj2.book_set.all())
orm 类与对象 与mysql的映射封装,但是有些复杂的写不出来,mysql可以写出来 ---超哥
基于
连表查询