SQLAlchemy:获取父类关联的子类对象

sqlalchemy:获取父类关联的子类对象

本文旨在帮助开发者理解 SQLAlchemy 中关系(relationship)的使用。当使用 SQLAlchemy 定义了父类和子类之间的关系后,直接访问父类的子类列表可能会得到空列表。这是因为 SQLAlchemy 默认情况下不会立即加载关系,需要在 flush() 或 commit() 操作后才会更新关系。本文将通过示例代码,演示如何通过 flush() 方法或者在创建父类对象时手动关联子类对象来正确地获取父类关联的子类对象。

理解 SQLAlchemy 关系(Relationship)

SQLAlchemy 的关系(relationship)功能用于定义表之间的关联。在 ORM 层面,它允许我们像访问对象的属性一样访问关联表的数据。例如,一个 Parent 类可以有一个 children 关系,指向多个 Child 类对象。

在定义关系时,需要指定 back_populates 参数,以便 SQLAlchemy 知道关系的另一端是什么。例如,在 Parent 类中,children = relationship(‘Child’, back_populates=’parent’) 表示 Parent 类有一个名为 children 的关系,它与 Child 类的 parent 关系相关联。

示例代码分析

以下代码展示了如何定义 Parent 和 Child 类,并使用 SQLAlchemy 创建表和插入数据:

import sysfrom sqlalchemy import (    create_engine,    Integer,    String,    BigInteger,)from sqlalchemy.schema import (    Column,    ForeignKey,)from sqlalchemy.sql import selectfrom sqlalchemy.orm import declarative_base, Session, aliased, relationship, joinedloadBase = declarative_base()# 替换为你的数据库用户名、密码和数据库名username, password, db = "your_username", "your_password", "your_database"engine = create_engine(f"postgresql+psycopg2://{username}:{password}@/{db}", echo=False)class Parent(Base):    __tablename__ = "parents"    id = Column(Integer, primary_key=True)    name = Column(String)    children = relationship('Child', back_populates='parent')class Child(Base):    __tablename__ = "childs"    id = Column(Integer, primary_key=True)    name = Column(String)    parent_id = Column(Integer, ForeignKey('parents.id'))    parent = relationship('Parent', back_populates='children')Base.metadata.create_all(engine)

注意: 将 your_username, your_password, your_database 替换成你自己的数据库信息。

获取关联对象的方法

方法一:使用 flush() 方法

flush() 方法将当前会话中的所有更改同步到数据库,包括插入、更新和删除操作。在 flush() 方法执行后,SQLAlchemy 会更新对象之间的关系。

def test1():    """"""    with Session(engine) as session:        mother = Parent(id=1, name='Sarah')        c1 = Child(id=22, parent_id=mother.id, name='Alice')        c2 = Child(id=23, parent_id=mother.id, name='Bob')        # Children and parent(s) are not set.        assert not mother.children and not c1.parent and not c2.parent        session.add(mother)        session.add(c1)        session.add(c2)        # Nothing changed.        assert not mother.children and not c1.parent and not c2.parent        session.flush()        # Now children and parent(s) are set.        assert mother.children and c1.parent and c2.parenttest1()

在这个例子中,我们首先创建了 Parent 和 Child 对象,并将它们添加到会话中。在调用 flush() 方法之前,mother.children 仍然是空的。但是在调用 flush() 方法之后,mother.children 会被更新为包含 c1 和 c2 对象。

方法二:手动关联对象

另一种方法是在创建 Parent 对象时,手动将 Child 对象添加到 children 列表中。

def test2():    """"""    with Session(engine) as session:        c1 = Child(id=22, name='Alice')        c2 = Child(id=23, name='Bob')        mother = Parent(id=1, name='Sarah', children=[c1, c2])        # Children and parents are now set but their parent_ids are not set.        assert mother.children and c1.parent and c2.parent and not c1.parent_id and not c2.parent_id        session.add(mother)        session.add(c1)        session.add(c2)        # Nothing changed.        assert mother.children and c1.parent and c2.parent and not c1.parent_id and not c2.parent_id        session.flush()        # Now children are set and parent ids are set.        assert mother.children and c1.parent and c2.parent and c1.parent_id and c2.parent_idtest2()

在这个例子中,我们在创建 mother 对象时,将 c1 和 c2 对象添加到 children 列表中。这样,在创建 mother 对象之后,mother.children 就会包含 c1 和 c2 对象。但是,需要注意的是,此时 c1 和 c2 对象的 parent_id 仍然没有设置,需要在调用 flush() 方法之后才会设置。

注意事项

在 SQLAlchemy 中,关系的加载方式有多种,包括 lazy、eager 和 joined。默认情况下,关系是 lazy 加载的,这意味着只有在访问关系时才会加载数据。如果需要立即加载关系,可以使用 joinedload 或 eagerload 方法。flush() 方法只是将更改同步到数据库,但不会提交事务。如果需要提交事务,需要调用 commit() 方法。在处理大量数据时,频繁调用 flush() 方法可能会影响性能。可以考虑批量插入数据,并在最后一次性调用 flush() 方法。

总结

通过本文的介绍,相信你已经了解了如何在 SQLAlchemy 中获取父类关联的子类对象。flush() 方法在 SQLAlchemy 中起着非常重要的作用,它可以同步会话中的更改,并更新对象之间的关系。在实际开发中,可以根据具体情况选择合适的方法来获取关联对象。

以上就是SQLAlchemy:获取父类关联的子类对象的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1371464.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
python中如何使用matplotlib绘制折线图_Matplotlib绘制折线图入门教程
上一篇 2025年12月14日 11:28:30
Python怎么将布尔值转换为整数_Python布尔型与整型转换方法
下一篇 2025年12月14日 11:28:39

相关推荐

  • Golang JSON序列化:控制敏感字段暴露的最佳实践

    本教程探讨golang中如何高效控制结构体字段在json序列化时的可见性。当需要将包含敏感信息的结构体数组转换为json响应时,通过利用`encoding/json`包提供的结构体标签,特别是`json:”-“`,可以轻松实现对特定字段的忽略,从而避免敏感数据泄露,确保api…

    2026年5月10日
    000
  • 《魔兽世界》将于6月11日开启国服回归技术测试

    《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试

    《%ign%ignore_a_1%re_a_1%》官方宣布,将于6月11日开启国服回归技术测试,时间为7天,并称可以在6月内正式开服,玩家们可以访问官网下载战网客户端并预下载“巫妖王之怒”客户端,技术测试详情见下图。 WordAi WordAI是一个AI驱动的内容重写平台 53 查看详情 以上就是《…

    2026年5月10日 用户投稿
    200
  • 如何在HTML中插入表单元素_HTML表单控件与输入类型使用指南

    HTML表单通过标签构建,包含action和method属性定义数据提交目标与方式,常用input类型如text、password、email等适配不同输入需求,配合label、required、placeholder提升可用性,结合textarea、select、button等控件实现完整交互,是…

    2026年5月10日
    000
  • 前端缓存策略与JavaScript存储管理

    根据数据特性选择合适的存储方式并制定清晰的读写与清理逻辑,能显著提升前端性能;合理运用Cookie、localStorage、sessionStorage、IndexedDB及Cache API,结合缓存策略与定期清理机制,可在保证用户体验的同时避免安全与性能隐患。 前端缓存和JavaScript存…

    2026年5月10日
    100
  • c++如何实现UDP通信_c++基于UDP的网络通信示例

    UDP通信基于套接字实现,适用于实时性要求高的场景。1. 流程包括创建套接字、绑定地址(接收方)、发送(sendto)与接收(recvfrom)数据、关闭套接字;2. 服务端监听指定端口,接收客户端消息并回传;3. 客户端发送消息至服务端并接收响应;4. 跨平台需处理Winsock初始化与库链接,编…

    2026年5月10日
    000
  • PHP安全文件下载:防止直链与保护资源

    本文旨在解决通过检查元素获取直链下载文件的问题,并提供一种安全的PHP服务器端文件交付方案。核心思想是利用PHP作为文件代理,通过设置HTTP响应头直接将文件发送给用户,从而隐藏文件的实际存储路径,有效防止未经授权的直接链接访问。 客户端下载链接的风险与局限性 在构建下载页面时,开发者常常面临一个挑…

    2026年5月10日
    100
  • Go语言连接外部MySQL数据库:DSN配置与常见错误解析

    本文详细阐述了go语言使用`go-sql-driver/mysql`驱动连接外部mysql数据库的正确方法。重点介绍了数据源名称(dsn)的规范格式,特别是主机地址部分的配置,以避免常见的“getaddrinfow: the specified class was not found.”等网络解析错…

    2026年5月10日
    000
  • 深入理解 Laravel Session::put:避免常见陷阱与实现表单限流

    本文旨在深入探讨 laravel 框架中 `session::put` 方法的正确用法及其常见误区。针对用户在实现表单提交限流时遇到的问题,详细阐述了 `session::put` 必须提供键值对的原理,并提供了如何在控制器中利用会话机制有效防止重复提交的实战代码示例。通过本文,读者将掌握 lara…

    2026年5月10日
    000
  • 如何使用AutoKeras训练AI大模型?自动构建神经网络的指南

    AutoKeras在AI大模型训练中扮演“智能建筑师”角色,通过自动化神经架构搜索与超参数优化,加速模型开发迭代。它基于Keras/TensorFlow,支持图像、文本、结构化数据任务,提供ImageClassifier、TextClassifier等接口,用户只需设定max_trials和epoc…

    2026年5月10日
    300
  • 实时音频转音素实现2D角色唇语同步教程

    本文详细介绍了如何将实时麦克风音频转换为音素,以实现2D角色唇语同步。核心方法是分两步走:首先利用语音转文本(STT)服务(如Python SpeechRecognition库)将实时音频转换为单词,然后使用CMU Dict库将这些单词映射为对应的音素。文章还将探讨如何进一步将CMU音素转换为国际音…

    2026年5月10日
    000
  • 使用SMTP.js发送邮件:客户端集成、常见问题与最佳实践指南

    本文深入探讨了使用SMTP.js库在前端发送邮件时可能遇到的问题,特别是与Elastic Email集成时的挑战。我们将分析代码中常见的异步处理错误、条件函数定义陷阱,并提供修正后的代码示例和最佳实践。重点强调了正确处理Promise链、确保函数可访问性以及客户端邮件发送的安全考量,帮助开发者构建更…

    2026年5月10日
    000
  • PHP动态网页数据库备份恢复_PHP动态网页MySQL数据库备份教程

    答案:PHP动态网页的MySQL数据库备份与恢复需通过定期导出SQL文件并安全存储来保障数据安全,核心方法包括使用mysqldump命令行工具实现高效灵活的自动化备份,利用phpMyAdmin图形化工具进行手动导出导入以降低操作门槛,以及通过PHP脚本调用系统命令将备份过程集成到应用中;恢复时可采用…

    2026年5月10日
    000
  • php登录怎么实现_php用户登录系统完整实现

    <blockquote>PHP用户登录系统的核心是安全验证与会话管理。首先创建POST提交的登录表单,避免敏感信息暴露;后端通过session_start()启动会话,使用trim()和htmlspecialchars()清理输入,防止XSS攻击;利用PDO预处理语句查询数据库,防止SQ…

    用户投稿 2026年5月10日
    000
  • WordPress自定义主题中根据文章数量动态显示/隐藏“查看更多”按钮的教程

    本教程旨在指导开发者如何在wordpress自定义主题中,根据特定文章类型和分类的实际数量,动态控制“查看更多”按钮的显示与隐藏。我们将利用 wp_query 及其 found_posts 属性,精确判断符合条件的文章总数,从而在有更多文章时显示按钮,在无文章时显示提示信息,优化用户体验。 引言 在…

    2026年5月10日
    000
  • Flexbox布局中带标签文本域的重叠问题及解决方案

    本文探讨了在使用css flexbox布局和spectre.css框架时,为文本域添加标签可能导致内容重叠的问题。核心原因在于父容器固定高度与子元素`height: 100%`的冲突,导致文本域未能正确计算标签所占空间。解决方案是移除父容器的固定高度,并为文本域设置响应式的视口高度(`vh`)值,确…

    2026年5月10日
    300
  • 在PHP中实现MySQL数据插入时避免重复记录的策略

    本文将探讨在php应用中向mysql数据库插入数据时,如何有效避免重复记录的产生。针对当主键或唯一索引字段值已存在的情况,我们将介绍使用`insert ignore`语句的策略,以确保数据完整性并防止不必要的重复插入,从而简化数据管理逻辑。 引言:数据完整性与重复记录问题 在数据库管理中,数据完整性…

    2026年5月10日
    000
  • 解决jQuery动态修改表单Action后提交失败的问题

    本教程旨在解决使用jQuery动态修改表单action属性后提交失败的问题。通过将逻辑绑定到提交按钮的click事件而非表单的submit事件,并在修改action后手动触发表单提交,可以有效确保表单携带正确的动态action属性成功提交,避免页面重载而不执行预设行为。 在web开发中,我们经常需要…

    2026年5月10日
    000
  • python如何将列表转换为字符串_python列表与字符串相互转换技巧

    将列表转换为字符串需用join()方法,确保元素均为字符串类型;含非字符串元素时应先用列表推导式结合str()转换。 在Python中,将列表转换为字符串最常见且高效的方式是使用字符串的 join() 方法;而将字符串转换为列表,则主要依赖于字符串的 split() 方法,或者针对特定需求使用 li…

    2026年5月10日
    200
  • PHP 动态 SQL WHERE 子句构建:避免重复 AND 的策略

    本文探讨了在 php 中动态构建 sql 查询 `where` 子句时常见的“`where and`”语法错误及其解决方案。通过逐步构建条件字符串,确保第一个条件不带 `and`,后续条件正确使用 `and` 连接,从而生成符合 sql 规范的查询语句,提高代码的健壮性和可读性。 动态构建 SQL …

    2026年5月10日
    200
  • PHP中基于用户角色的页面访问控制实践

    本教程详细讲解如何在PHP应用程序中利用会话(Session)机制实现基于用户角色的页面访问控制。通过正确的session_start()调用、用户登录时的角色信息存储,以及在受保护页面进行严格的会话和角色类型检查,确保只有特定用户(如“manager”)才能访问指定页面,从而有效防止未经授权的访问…

    2026年5月10日
    100

发表回复

登录后才能评论
关注微信