3. 通过 loader_filters 改变loader 查询条件

存在一种情况, 我们希望dataloader 中可以添加一些额外的过滤条件,比如我们希望过滤掉标记为deleted 的 comments 和 feedbacks. 或者在某些情况下,查找标为deleted的记录

dataloader filter 参数可以做到

 1class CommentLoader(DataLoader):
 2   deleted: bool
 3   async def batch_load_fn(task_ids):
 4      async with db.async_session() as session:
 5            res = await session.execute(select(Comment)
 6                  .where(Commend.deleted.is_(self.deleted))
 7                  .where(Comment.task_id.in_(task_ids)))
 8            rows = res.scalars().all()
 9            return build_list(rows, task_ids, lambda x: x.task_id)
10
11class FeedbackLoader(DataLoader):
12   deleted: bool
13   async def batch_load_fn(comment_ids):
14      async with db.async_session() as session:
15            res = await session.execute(select(Feedback)
16               .where(feedback.deleted.is_(self.deleted))
17               .where(Feedback.comment_id.in_(comment_ids)))
18            rows = res.scalars().all()
19            return build_list(rows, comment_ids, lambda x: x.comment_id)
20
21class Task(Base):
22   __tablename__ = "task"
23
24   id: Mapped[int] = mapped_column(primary_key=True)
25   name: Mapped[str]
26
27class Comment(Base):
28   __tablename__ = "comment"
29
30   id: Mapped[int] = mapped_column(primary_key=True)
31   task_id: Mapped[int] = mapped_column()
32   content: Mapped[str]
33   deleted: Mapped[bool]
34
35class Feedback(Base):
36   __tablename__ = "feedback"
37
38   id: Mapped[int] = mapped_column(primary_key=True)
39   comment_id: Mapped[int] = mapped_column()
40   content: Mapped[str]
41   deleted: Mapped[bool]
42
43class FeedbackSchema(BaseModel):
44   id: int
45   comment_id: int
46   content: str
47
48   class Config:
49      orm_mode = True
50
51class CommentSchema(BaseModel):
52   id: int
53   task_id: int
54   content: str
55   feedbacks: List[FeedbackSchema] = []
56   def resolve_feedbacks(self, feedback_loader=LoaderDepend(feedback_batch_load_fn)):
57      return feedback_loader.load(self.id)
58
59   class Config:
60      orm_mode = True
61
62class TaskSchema(BaseModel):
63   id: int
64   name: str
65
66   comments: List[CommentSchema] = []
67   def resolve_comments(self, comment_loader=LoaderDepend(comment_batch_load_fn)):
68      return comment_loader.load(self.id)
69
70   class Config:
71      orm_mode = True
72
73@app.get('/tasks', response_model=List[TaskSchema])
74async def get_tasks(private:bool= Query(default=True),
75                  session: AsyncSession = Depends(db.get_session)):
76   tasks = (await session.execute(select(Task))).scalars().all()
77   loder_filters = {
78      CommentLoader: {
79         'deleted': False
80      },
81      FeedbackLoader: {
82         'deleted': False
83      },
84   }
85
86   tasks = await Resolver(loader_filters=loader_filters).resolve(tasks)
87   return tasks