已解决
Django——模型层补充
来自网友在路上 150850提问 提问时间:2023-11-19 00:33:47阅读次数: 50
最佳答案 问答题库508位专家为你答疑解惑
django中如何开启事务
'''
# 事务的四大特性: # 简称: ACID# A: 原子性事务对数据的修改操作要么同时成功, 要么一个都别想成功(回滚)# C: 一致性事务的执行必然是从一个一致性的状态, 转变到另一个一致性的状态.# I: 隔离性对于并发的事务, 每个事务之间是互相隔离的, 互不影响的. 如果是争对同一份数据的修改操作, 那么将并发变成串行, 牺牲了效率, 但是保证了数据的安全.# D: 持久性:事务执行完毕对数据的修改操作是永久性的. 即便在数据库管理系统异常, 提交的结果对数据的修改也是永久的.# 原生SQL中的事务操作步骤1. 开启 start transaction;2. 回滚 rollback;3. 确认 commit;
'''from django.db import transaction
try:with transaction.atomic():# ORM执行SQL语句...# 在with代码快内书写的所有orm操作都是属于同一个事务
except Exception as e:print(e)print('执行其他操作')
orm语句的特点: 惰性查询
"""
如果你仅仅只是书写了orm语句 在后面根本没有用到该语句所查询出来的参数
那么orm会自动识别 直接不执行惰性: res = models.Book.objects.all()
执行: print(res)
"""
Django ORM执行原生SQL
'''
extra: 标识要做格外的操作
select={'publish_date': 'date_format(publish_date, "%%Y-%%m")'}: 执行原生的sql语句用到原生sql日期函数date_formatpublish_date: 定义一个key, 通过values后面可以拿到结果. 类始于annotate分组一样
'''
# 需求: 查询数据名称和出版时间(年-月)
res = models.Book.objects.extra(select={'publish_date': 'date_format(publish_date, "%%Y-%%m")'}).values('name', 'publish_date')
print(res) # <QuerySet [{'publish_date': '2020-05', 'name': '西游记'}, {'publish_date': '2020-05', 'name': '水浒传'}]>
数据库查询优化
1. only 和 defer
'''
使用: 直接在objects后面连用
返回: only 和 defer都返回QuerySet对象
区别: only: only括号内指定的字段, 在被查询的时候不会走数据库. defer: defer括号内指定的字段, 在被查询的时候会走数据库
特殊: 如果仅仅使用all. 没有执行结果它是惰性的, 但是一旦执行过一次. 第二次拿到all的返回值. 是不需要重新走数据库
'''# 1. only
# res = models.Publish.objects.only('name')
res = models.Publish.objects.all()
print(res) # <QuerySet [<Publish: 东方出版社>, <Publish: 北方出版社>]>
for i in res:print(i.name) # 点击only括号内的字段不会走数据库for i in res:print(i.addr) # 点击only括号内没有的字段会重新走数据库. 如果是all的情况就不需要走.
"""
(0.001) SELECT `app01_publish`.`id`, `app01_publish`.`addr` FROM `app01_publish` WHERE `app01_publish`.`id` = 1; args=(1,)
(0.001) SELECT `app01_publish`.`id`, `app01_publish`.`addr` FROM `app01_publish` WHERE `app01_publish`.`id` = 2; args=(2,)
"""# 2. defer
res = models.Publish.objects.defer('name')
print(res) # <QuerySet [<Publish: 东方出版社>, <Publish: 北方出版社>]>for i in res:print(i.name) # 点defer括号内的字段会走数据库
'''
(0.000) SELECT `app01_publish`.`id`, `app01_publish`.`name` FROM `app01_publish` WHERE `app01_publish`.`id` = 1; args=(1,)
(0.000) SELECT `app01_publish`.`id`, `app01_publish`.`name` FROM `app01_publish` WHERE `app01_publish`.`id` = 2; args=(2,)
'''for i in res:print(i.addr) # 点defer括号内的字段不会走数据库
2. select_related 和 prefetch_related
'''
使用: 直接在objects后面连用
返回: only 和 defer都返回QuerySet对象
区别: select_related: 内部使用连表查询. !!注意:!! 括号内只能放外键字段. 且只支持一对一, 一对多的表关系. 多对多不支持.内部通过1次性将2表查询出来封装成对象中, 下次查询这2表就无序走数据库了.prefetch_related: 内部使用子查询. 内部通过2次性将子查询结果查询出封装成对象中.下次查询这2表就无序走数据库了. (感觉视角: 感觉是一次性搞定的)
'''# 1. select_related 连表查询
'''
select_related内部直接先将Author与author_detail表连起来 然后一次性将大表里面的所有数据, 全部封装给查询出来的对象.
这个时候对象无论是点击book表的数据还是publish的数据都无需再走数据库查询了
'''
res = models.Author.objects.select_related('author_detail')
for i in res:print(i.author_detail.phone)
'''
(0.001) SELECT `app01_author`.`id`, `app01_author`.`name`, `app01_author`.`age`, `app01_author`.`author_detail_id`, `app01_authordetail`.`id`, `app01_authordetail`.`phone`, `app01_authordetail`.`addr` FROM `app01_author` INNER JOIN `app01_authordetail` ON (`app01_author`.`author_detail_id` = `app01_authordetail`.`id`); args=()
'''# 下次查询这2表就无序走数据库了.
for i in res:print(i.author_detail.phone) # prefetch_related 子查询
'''
prefetch_related该方法内部其实就是子查询
将子查询查询出来的所有结果也给你封装到对象中
给你的感觉好像也是一次性搞定的
'''
res = models.Author.objects.prefetch_related('author_detail')
for i in res:print(i.author_detail.phone)
'''
(0.000) SELECT `app01_author`.`id`, `app01_author`.`name`, `app01_author`.`age`, `app01_author`.`author_detail_id` FROM `app01_author`; args=()
(0.001) SELECT VERSION(); args=None
(0.000) SELECT `app01_authordetail`.`id`, `app01_authordetail`.`phone`, `app01_authordetail`.`addr` FROM `app01_authordetail` WHERE `app01_authordetail`.`id` IN (1, 2, 3); args=(1, 2, 3)
'''# 下次查询这2表就无序走数据库了.
for i in res:print(i.author_detail.phone)
in_bulk 根据主键ID进行查找
dic_obj = models.Book.objects.in_bulk([1, 2])
print(type(dic_obj)) # <class 'dict'>
for pk, book_obj in dic_obj.items():print(pk, book_obj.name)'''
1 西游记
2 水浒传
'''
查看全文
99%的人还看了
相似问题
- MySQL数据库:开源且强大的关系型数据库管理系统
- 【腾讯云云上实验室-向量数据库】探索腾讯云向量数据库:全方位管理与高效利用多维向量数据的引领者
- 【史上最细教程】服务器MySQL数据库完成主从复制
- 字符串结尾空格比较相关参数BLANK_PAD_MODE(DM8:达梦数据库)
- 缓存雪崩、击穿、穿透及解决方案_保证缓存和数据库一致性
- Redis 与其他数据库的不同之处 | Navicat
- 多协议数据库管理软件 Navicat Premium 16 mac中文版功能
- (数据库管理系统)DBMS与(数据库系统)DBS的区别
- duplicate复制数据库单个数据文件复制失败报错rman-03009 ora-03113
- 数据库课后习题加真题
猜你感兴趣
版权申明
本文"Django——模型层补充":http://eshow365.cn/6-38791-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: CentOS 7.9 安装 nginx
- 下一篇: 第六章 图(上)【图的基本概念和存储】