Optimize relationship loading

在处理模型中的任何类型的关系时,无论是一对多(One-To-Many)、多对一(Many-To-One)还是多对多(Many-To-Many),SQLAdmin 都会在编辑页面加载相关的模型。

例如,如果我们有以下模型定义:

class Parent(Base):
    __tablename__ = "parent_table"

    id = mapped_column(Integer, primary_key=True)
    children = relationship("Child", back_populates="parent")


class Child(Base):
    __tablename__ = "child_table"

    id = mapped_column(Integer, primary_key=True)
    parent_id = mapped_column(ForeignKey("parent_table.id"))
    parent = relationship("Parent", back_populates="children")

当我们在 Admin 中编辑一个 Parent 对象时,编辑页面会显示一个 HTML 下拉选择框,加载所有可能的 Child 对象供选择。

对于小型项目来说,这种方式是可以接受的,但如果表中有几百条记录,它将变得非常慢且低效。实际上,每次访问编辑页面时,都会加载 Child 表的所有记录。

为了解决这个问题,您可以使用配置中的表单选项。

以下是几种改善的方式:

使用 form_ajax_refs

与其在编辑 Parent 对象时加载所有 Child 对象,不如使用 form_ajax_refs 来通过 AJAX 调用加载 Child 对象:

这将允许您使用 id 字段搜索 Child 对象,并且还可以对结果进行排序。

使用 form_columnsform_excluded_columns

另一种选择(虽然不如前一种方法有用)是,如果您不希望在 Parent 对象的编辑页面中编辑 children 关系,您可以将其排除,或者仅包括应在表单中显示的列。

使用 form_edit_query 自定义编辑表单数据

如果您希望完全自定义查询以填充编辑对象表单,您可以重写 form_edit_query 函数,使用您自己的 SQLAlchemy 查询。在以下示例中,重写默认查询将允许您筛选关系,只显示与父对象相关的 Child 对象:

通过这些方法,您可以优化与关系相关的数据加载,避免一次性加载所有记录,从而提高性能和响应速度。

最后更新于