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