0

0

SQLAlchemy 如何获取“子”类中的对象?

霞舞

霞舞

发布时间:2025-09-13 20:05:01

|

273人浏览过

|

来源于php中文网

原创

sqlalchemy 如何获取“子”类中的对象?

本文介绍了在使用 SQLAlchemy 进行数据库操作时,如何正确地获取父类关联的子类对象。重点在于理解 SQLAlchemy 的关系(relationship)以及何时进行 flush 操作,以确保对象之间的关联关系被正确地建立和加载。通过示例代码,演示了两种实现方式,帮助开发者避免常见的关系映射问题。

在使用 SQLAlchemy 进行对象关系映射(ORM)时,经常需要在父类对象中获取关联的子类对象。然而,初学者可能会遇到类似“无法立即获取到关联子对象”的问题。这是因为 SQLAlchemy 的关系(relationship)在默认情况下,并不会立即加载所有关联对象。需要理解 SQLAlchemy 的 session 管理和 flush 机制,才能正确地获取和操作这些关联对象。

理解 SQLAlchemy 的 Relationship

在 SQLAlchemy 中,relationship 用于定义表之间的关系。例如,一个 Parent 类可以拥有多个 Child 类实例,而 Child 类实例又关联到一个 Parent 类实例。back_populates 参数用于指定反向引用,使得可以通过 parent.children 和 child.parent 访问关联对象。

from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Column, String, Integer, ForeignKey

Base = declarative_base()

class Parent(Base):
    __tablename__ = 'parents'

    id = Column(Integer, primary_key=True)
    name = Column(String(20))

    children = relationship('Child', back_populates='parent')


class Child(Base):
    __tablename__ = 'children'

    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parents.id'))
    name = Column(String(20))

    parent = relationship('Parent', back_populates='children')

延迟加载与 Flush 操作

默认情况下,SQLAlchemy 的 relationship 使用延迟加载(lazy loading)。这意味着,只有在真正访问 parent.children 属性时,才会执行数据库查询来加载子对象。 更重要的是,即使你创建了 Parent 和 Child 对象,并将它们添加到 Session 中,它们之间的关系也不会立即建立。需要执行 session.flush() 操作,才能将对象的更改刷新到数据库,并建立对象之间的关系。

示例代码

以下示例展示了两种获取关联子对象的方法:

易优cms汽车车辆租赁源码1.7.2
易优cms汽车车辆租赁源码1.7.2

由于疫情等原因大家都开始习惯了通过互联网上租车服务的信息多方面,且获取方式简便,不管是婚庆用车、旅游租车、还是短租等租车业务。越来越多租车企业都开始主动把租车业务推向给潜在需求客户,所以如何设计一个租车网站,以便在同行中脱颖而出就重要了,易优cms针对租车行业市场需求、目标客户、盈利模式等,进行策划、设计、制作,建设一个符合用户与搜索引擎需求的租车网站源码。 网站首页

下载

方法一:先添加到 Session,然后 Flush

from sqlalchemy import create_engine
from sqlalchemy.orm import Session

# 假设你已经定义了 Parent 和 Child 类,并创建了 engine
engine = create_engine('sqlite:///:memory:', echo=True) # 使用内存数据库方便演示
Base.metadata.create_all(engine) # 创建表

def test1():
    with Session(engine) as session:
        mother = Parent(name='Sarah')
        c1 = Child(name='Alice')
        c2 = Child(name='Bob')

        # 关键:将 parent_id 设置为 mother.id
        c1.parent = mother
        c2.parent = mother

        # 添加到 Session
        session.add(mother)
        session.add(c1)
        session.add(c2)

        # 刷新 Session,将更改同步到数据库
        session.flush()

        # 现在 mother.children 包含了 c1 和 c2
        print(mother.children)
        assert len(mother.children) == 2
        assert c1.parent == mother
        assert c2.parent == mother

test1()

方法二:在创建 Parent 对象时,直接关联 Child 对象

from sqlalchemy import create_engine
from sqlalchemy.orm import Session

# 假设你已经定义了 Parent 和 Child 类,并创建了 engine
engine = create_engine('sqlite:///:memory:', echo=True) # 使用内存数据库方便演示
Base.metadata.create_all(engine) # 创建表

def test2():
    with Session(engine) as session:
        c1 = Child(name='Alice')
        c2 = Child(name='Bob')

        # 在创建 Parent 对象时,直接将 children 关联
        mother = Parent(name='Sarah', children=[c1, c2])

        # 添加到 Session
        session.add(mother)
        session.add(c1)
        session.add(c2)

        # 刷新 Session,将更改同步到数据库
        session.flush()

        # 现在 mother.children 包含了 c1 和 c2
        print(mother.children)
        assert len(mother.children) == 2
        assert c1.parent == mother
        assert c2.parent == mother

test2()

注意事项

  1. session.flush() 的作用: flush() 操作将 Session 中的更改同步到数据库,但不提交事务。这意味着,如果后续操作失败,可以回滚事务,撤销这些更改。
  2. session.commit() 的作用: commit() 操作提交事务,将更改永久保存到数据库。
  3. 显式设置关系: 确保在将对象添加到 Session 之前,显式地设置对象之间的关系(例如,通过 child.parent = parent 或在创建 Parent 对象时,直接将 Child 对象添加到 children 列表中)。
  4. 数据库引擎的选择: 在示例中使用了内存数据库 sqlite:///:memory:,这方便了演示,但实际应用中需要根据需求选择合适的数据库引擎。
  5. 延迟加载的影响: 理解延迟加载的机制,可以避免不必要的数据库查询,提高性能。如果需要立即加载关联对象,可以使用 joinedload 等加载策略。

总结

要正确地获取 SQLAlchemy 中父类关联的子类对象,需要理解 relationship 的定义、session.flush() 的作用,以及显式地设置对象之间的关系。通过合理地使用这些机制,可以有效地管理对象之间的关联关系,并编写出高效、可维护的数据库应用程序。

相关专题

更多
session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

307

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

733

2023.10.18

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

88

2025.08.19

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

344

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2074

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

347

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

253

2023.09.05

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

322

2023.10.09

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Laravel 5.8 中文文档手册
Laravel 5.8 中文文档手册

共74课时 | 84.6万人学习

SESSION实现登录与验证
SESSION实现登录与验证

共10课时 | 9.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号