我刚刚添加了预取功能,应该可以解决您的问题。您可以从以下位置获取工作代码GitHub 存储库 https://github.com/ponyorm/pony。此功能将成为即将发布的 Pony ORM 0.5.4 的一部分。
现在你可以写:
q = q.prefetch(Supplier)
or
q = q.prefetch(Order.supplier)
Pony会自动加载相关supplier
对象。
下面我将使用带有学生、组和部门的标准 Pony 示例,展示几个带有预取的查询。
from pony.orm.examples.presentation import *
仅加载 Student 对象,不进行任何预取:
students = select(s for s in Student)[:]
将学生与小组和部门一起加载:
students = select(s for s in Student).prefetch(Group, Department)[:]
for s in students: # no additional query to the DB is required
print s.name, s.group.major, s.group.dept.name
与上面相同,但指定属性而不是实体:
students = select(s for s in Student).prefetch(Student.group, Group.dept)[:]
for s in students: # no additional query to the DB is required
print s.name, s.group.major, s.group.dept.name
加载学生及其课程(多对多关系):
students = select(s for s in Student).prefetch(Student.courses)
for s in students:
print s.name
for c in s.courses: # no additional query to the DB is required
print c.name
作为参数prefetch()
您可以指定实体和/或属性的方法。如果您指定了一个实体,则所有to-one该类型的属性将被预取。如果您指定了一个属性,那么将预取该特定属性。仅当显式指定时才会预取对多属性(如Student.courses
例子)。预取是递归进行的,因此您可以加载长链属性,例如student.group.dept
.
当预取对象时,默认情况下会加载其所有属性,除了惰性属性和多对多属性之外。如果需要,您可以显式预取惰性属性和多对多属性。
我希望这种新方法能够完全覆盖您的用例。如果某些内容未按预期工作,请在 GitHub 上开始新问题 https://github.com/ponyorm/pony/issues/new。您还可以在以下位置讨论功能并提出功能请求:Pony ORM 邮件列表 http://ponyorm-list.ponyorm.com.
附:我不确定您使用的存储库模式是否能给您带来真正的好处。我认为它实际上增加了模板渲染和存储库实现之间的耦合,因为当模板代码开始使用新属性时,您可能需要更改存储库实现(即向预取列表添加新实体)。与顶级@db_session
装饰器,您只需将查询结果发送到模板,一切都会自动发生,无需显式预取。但也许我遗漏了一些东西,所以我有兴趣看到有关在您的案例中使用存储库模式的好处的其他评论。