sqlalchemy expire_all 方法详解,强制刷新会话缓存

这篇具有很好参考价值的文章主要介绍了sqlalchemy expire_all 方法详解,强制刷新会话缓存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在 SQLAlchemy 中,expire_all() 方法是 Session 类的一个重要方法,用于使会话(Session)中所有当前加载的对象过期。这意味着下次访问任何已加载对象的属性时,SQLAlchemy 将从数据库中重新加载这些对象的最新状态。这是一个强制刷新加载对象状态的方法,确保您获取的是数据库中的最新数据。

功能

当您调用 session.expire_all() 时,会发生以下事情:

  1. 标记所有对象为过期:在该会话中加载的所有对象都被标记为“过期”。这意味着它们的当前状态将被丢弃,而不是从会话的缓存中提取。

  2. 延迟加载:在下次访问这些对象的任何属性时,SQLAlchemy 会自动从数据库中重新加载它们的最新状态。这是一个延迟操作,只有在实际访问属性时才会触发。

  3. 不影响未修改的对象:即使对象自加载后未被修改,它们的状态也会被清除并在下次访问时重新加载。

使用场景

您可能会在以下情况下使用 expire_all():

  1. 保证数据一致性:在长时间运行的会话中,为了确保获取到数据库中的最新数据,可以使用 expire_all() 方法。

  2. 避免脏读:在有可能发生并发修改的场景中,使用 expire_all() 可以防止读取到过时的数据。

  3. 手动刷新状态:在某些复杂的交互逻辑中,您可能需要手动刷新对象状态,以确保应用逻辑的正确性。

示例

from sqlalchemy.orm import sessionmaker
from my_model import MyModel  # 假设您有一个模型类 MyModel
from sqlalchemy import create_engine

# 创建会话
engine = create_engine("sqlite:///mydatabase.db")
Session = sessionmaker(bind=engine)
session = Session()

# 查询并使用对象
my_object = session.query(MyModel).first()
print(my_object.some_attribute)

# 确保从数据库重新加载对象
session.expire_all()

# 当再次访问属性时,将从数据库重新加载它的最新状态
print(my_object.some_attribute)

SQLAlchemy 2.0 代码展示

print("=====================================会话缓存==================================================")

# 第一次查询,并加载用户的所有关联部门项
sql1 = select(models.VadminUser).where(models.VadminUser.id == 1).options(joinedload(models.VadminUser.depts))
queryset1 = await self.db.scalars(sql1)
user1 = queryset1.unique().first()
print(f"用户编号:{user1.id} 用户姓名:{user1.name} 关联部门 {[i.name for i in user1.depts]}")

# 第二次即使没有加载用户关联的部门,同样可以访问,因为这里会默认从会话缓存中获取
sql2 = select(models.VadminUser).where(models.VadminUser.id == 1)
queryset2 = await self.db.scalars(sql2)
user2 = queryset2.first()
print(f"用户编号:{user2.id} 用户姓名:{user2.name} 关联部门 {[i.name for i in user2.depts]}")

# 使当前会话(Session)中所有已加载的对象过期,确保您获取的是数据库中的最新数据。
self.db.expire_all()

print("===================查询出来,即使没有通过.访问属性,同样会产生缓存=====================")

# 第一次查询,并加载用户的所有关联部门项,但是不访问用户的属性
sql3 = select(models.VadminUser).where(models.VadminUser.id == 1).options(joinedload(models.VadminUser.depts))
queryset3 = await self.db.scalars(sql3)
user3 = queryset3.unique().first()
print(f"没有访问属性,也会产生缓存")

# 第二次即使没有加载用户关联的部门,同样可以访问,因为这里会默认从会话缓存中获取
sql4 = select(models.VadminUser).where(models.VadminUser.id == 1)
queryset4 = await self.db.scalars(sql4)
user4 = queryset4.first()
print(f"用户编号:{user4.id} 用户姓名:{user4.name} 关联部门 {[i.name for i in user4.depts]}")

# 使当前会话(Session)中所有已加载的对象过期,确保您获取的是数据库中的最新数据。
self.db.expire_all()

print("=====================================数据列表会话缓存==================================================")

# 第一次查询出所有用户,并加载用户的所有关联部门项
sql5 = select(models.VadminUser).options(joinedload(models.VadminUser.depts))
queryset5 = await self.db.scalars(sql5)
datas5 = queryset5.unique().all()
for data in datas5:
    print(f"用户编号:{data.id} 用户姓名:{data.name} 关联部门 {[i.name for i in data.depts]}")

# 第二次即使没有加载用户关联的部门,同样可以访问,因为这里会默认从会话缓存中获取
sql6 = select(models.VadminUser)
queryset6 = await self.db.scalars(sql6)
datas6 = queryset6.unique().all()
for data in datas6:
    print(f"用户编号:{data.id} 用户姓名:{data.name} 关联部门 {[i.name for i in data.depts]}")

# 使当前会话(Session)中所有已加载的对象过期,确保您获取的是数据库中的最新数据。
self.db.expire_all()

print("===================expire 单个对象过期=====================")

# 第一次查询,并加载用户的所有关联部门项
sql7 = select(models.VadminUser).where(models.VadminUser.id == 1).options(joinedload(models.VadminUser.depts))
queryset7 = await self.db.scalars(sql7)
user7 = queryset7.unique().first()
print(f"用户编号:{user7.id} 用户姓名:{user7.name} 关联部门 {[i.name for i in user7.depts]}")

# 使当前会话(Session)中的 user7 对象过期,再次访问就会重新查询数据库数据
self.db.expire(user7)

# 第二次查询会发现会话中没有该对象的缓存,会重新在数据库中查询
sql8 = select(models.VadminUser).where(models.VadminUser.id == 1)
queryset8 = await self.db.scalars(sql8)
user8 = queryset8.first()
try:
    print(f"用户编号:{user8.id} 用户姓名:{user8.name} 关联部门 {[i.name for i in user8.depts]}")
except StatementError:
    print("访问部门报错了!!!!!")

# 使当前会话(Session)中所有已加载的对象过期,确保您获取的是数据库中的最新数据。
self.db.expire_all()

print("=========expire 单个对象过期后,重新访问之前对象的属性也会重新查询数据库,但是不会重新加载关系===========")

# 第一次查询,并加载用户的所有关联部门项
sql9 = select(models.VadminUser).where(models.VadminUser.id == 1).options(joinedload(models.VadminUser.depts))
queryset9 = await self.db.scalars(sql9)
user9 = queryset9.unique().first()
print(f"用户编号:{user9.id} 用户姓名:{user9.name} 关联部门 {[i.name for i in user9.depts]}")

# 使当前会话(Session)中的 user9 对象过期,再次访问就会重新查询数据库数据
self.db.expire(user9)

# 第二次查询会发现会话中没有该对象的缓存,会重新在数据库中查询,但是不会重新加载关系
try:
    print(f"用户编号:{user9.id} 用户姓名:{user9.name} 关联部门 {[i.name for i in user9.depts]}")
except StatementError:
    print("访问部门报错了!!!!!")

print("=====================================结束==================================================")

在这个示例中,使用 expire_all() 后,当再次访问 my_object.some_attribute 时,SQLAlchemy 将从数据库中重新加载 MyModel 对象的最新状态。文章来源地址https://www.toymoban.com/news/detail-793946.html

到了这里,关于sqlalchemy expire_all 方法详解,强制刷新会话缓存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue 组件强制刷新方式

    🏆 文章目标:记录前端开发中遇见的问题。 🍀 Vue 组件强制刷新方式 ✅ 创作者:Jay… 🎉 个人主页:Jay的个人主页 🍁 展望:若本篇讲解内容帮助到您,请帮忙点个赞吧,您的支持是我继续写作的最大动力,谢谢。🙏 为实现动态页签组件,根据页签的类型获取对应的co

    2023年04月22日
    浏览(86)
  • vue组件强制刷新的方式

    开发过程中,有时候会遇到这么一种情况,通过动态的赋值,但是dom没有及时更新,能够获取到动态赋的值,但是无法获取到双向绑定的dom节点,这就需要我们手动进行强制刷新组件 方式一: 刷新整个页面 方式二: 使用v-if标记;如果是刷新某个子组件,则可以通过v-if指令实现。我

    2024年02月15日
    浏览(64)
  • vue组件强制刷新的方案

    前言: Vue的双向绑定属于自动档;在特定的情况下,需要手动触发“刷新”操作,目前有四种方案可以选择: 刷新整个页面(最low的,可以借助route机制) 使用v-if标记(比较low的) 使用内置的forceUpdate方法(较好的) 使用key-changing优化组件(最好的) 刷新整个页面 使用

    2023年04月19日
    浏览(40)
  • mac如何强制刷新chorm浏览器

    在 macOS 上,你可以使用以下方法来强制刷新 Chrome 浏览器: 使用快捷键:按住 Shift 键 并同时点击 浏览器刷新按钮 。这会强制浏览器绕过缓存并重新加载当前页面。 使用开发者工具:按下 Option + Command + I 快捷键(或通过右键点击页面并选择 “Inspect”(检查)菜单)打开

    2024年02月15日
    浏览(91)
  • ES6 - promise.all和race方法的用法详解

    一、前言 谈谈你对Promise的理解? 答 :Promise用来解决异步回调问题,由于js是单线程的,很多异步操作都是依靠回调方法实现的,这种做法在逻辑比较复杂的回调嵌套中会相当复杂;也叫做回调地狱; promise用来将这种繁杂的做法简化,让程序更具备可读性,可维护性;pro

    2024年02月15日
    浏览(33)
  • 【vue】element强制刷新el-carousel的dom:

    一、问题: 二、分析: el-carouse里面的数据是最新的,但dom却是前一个的数据 注意:使用了 this.$forceUpdate(); 或 this.$set(xx,xx); ,没有效果 三、解决:

    2024年02月07日
    浏览(85)
  • Discuz论坛网站登录账号操作慢,必须强制刷新才会显示登录怎么办?

    飞飞发现在登录服务器大本营账号时,输入账号密码登录后还是显示的登录框,强制刷新后才知道已经登录了,每次都要刷新才能正常显示,非常影响用户体验,于是在网上找了类似的问题故障解决方法,目前问题已经解决,分享给你们参考。 首先我们在网站根目录 /uc_ser

    2024年01月18日
    浏览(67)
  • 高德+vue Object3DLayer强制刷新后找不到的问题

    报错错误展示: 解决方式一: 1.重构plugin 2.判断如果plugin为空,再次刷新地图 示例完整代码 ps:在最新一次项目中,需要在掩模上再添加一些3D板块,这个时候发现使用解决方法一还是不行,出现报错“Maximum call stack size exceeded”,查询得知这是因为异步获取数据所致,并且报

    2024年02月13日
    浏览(44)
  • SQLAlchemy详解

    SQLAlchemy 是 Python SQL 工具包和对象关系映射器,为应用程序开发人员提供 SQL 的全部功能和灵活性。 SQLAlchemy支持SQLite、PostgreSQL、Oracle、MySQL、MariaDB、Microsoft SQL Server等多种数据库。 我安装的版本是:SQLAlchemy==2.0.29。注意SQLAlchemy2.x以上的版本和1.x版本差别还是挺大的,注意版

    2024年04月08日
    浏览(31)
  • SQLAlchemy 中的会话(Session)缓存详解

    SQLAlchemy 的会话缓存(Session Cache)是 ORM 框架的核心特性之一,对于理解和高效使用 SQLAlchemy 至关重要。这个缓存机制主要作用在会话(Session)层面,提供了对数据库交互的中间缓存层。以下是对 SQLAlchemy 会话缓存的详细解释: 一级缓存:会话缓存也被称为一级缓存。它自动

    2024年02月02日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包