mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: optimize course retrieval by using joins to fetch authors in a single query
This commit is contained in:
parent
90938de5f0
commit
20bafafba0
1 changed files with 17 additions and 20 deletions
|
|
@ -133,42 +133,40 @@ async def get_course_meta(
|
||||||
# Avoid circular import
|
# Avoid circular import
|
||||||
from src.services.courses.chapters import get_course_chapters
|
from src.services.courses.chapters import get_course_chapters
|
||||||
|
|
||||||
# Get course with a single query
|
# Get course with authors in a single query using joins
|
||||||
course_statement = select(Course).where(Course.course_uuid == course_uuid)
|
course_statement = (
|
||||||
course = db_session.exec(course_statement).first()
|
select(Course, ResourceAuthor, User)
|
||||||
|
.outerjoin(ResourceAuthor, ResourceAuthor.resource_uuid == Course.course_uuid) # type: ignore
|
||||||
|
.outerjoin(User, ResourceAuthor.user_id == User.id) # type: ignore
|
||||||
|
.where(Course.course_uuid == course_uuid)
|
||||||
|
.order_by(ResourceAuthor.id.asc()) # type: ignore
|
||||||
|
)
|
||||||
|
results = db_session.exec(course_statement).all()
|
||||||
|
|
||||||
if not course:
|
if not results:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=404,
|
status_code=404,
|
||||||
detail="Course not found",
|
detail="Course not found",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Extract course and authors from results
|
||||||
|
course = results[0][0] # First result's Course
|
||||||
|
author_results = [(ra, u) for _, ra, u in results if ra is not None and u is not None]
|
||||||
|
|
||||||
# RBAC check
|
# RBAC check
|
||||||
await rbac_check(request, course.course_uuid, current_user, "read", db_session)
|
await rbac_check(request, course.course_uuid, current_user, "read", db_session)
|
||||||
|
|
||||||
# Start async tasks concurrently
|
# Start async tasks concurrently
|
||||||
tasks = []
|
tasks = []
|
||||||
|
|
||||||
# Task 1: Get course authors with their roles
|
# Task 1: Get course chapters
|
||||||
async def get_authors():
|
|
||||||
authors_statement = (
|
|
||||||
select(ResourceAuthor, User)
|
|
||||||
.join(User, ResourceAuthor.user_id == User.id) # type: ignore
|
|
||||||
.where(ResourceAuthor.resource_uuid == course.course_uuid)
|
|
||||||
.order_by(
|
|
||||||
ResourceAuthor.id.asc() # type: ignore
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return db_session.exec(authors_statement).all()
|
|
||||||
|
|
||||||
# Task 2: Get course chapters
|
|
||||||
async def get_chapters():
|
async def get_chapters():
|
||||||
# Ensure course.id is not None
|
# Ensure course.id is not None
|
||||||
if course.id is None:
|
if course.id is None:
|
||||||
return []
|
return []
|
||||||
return await get_course_chapters(request, course.id, db_session, current_user, with_unpublished_activities)
|
return await get_course_chapters(request, course.id, db_session, current_user, with_unpublished_activities)
|
||||||
|
|
||||||
# Task 3: Get user trail (only for authenticated users)
|
# Task 2: Get user trail (only for authenticated users)
|
||||||
async def get_trail():
|
async def get_trail():
|
||||||
if isinstance(current_user, AnonymousUser):
|
if isinstance(current_user, AnonymousUser):
|
||||||
return None
|
return None
|
||||||
|
|
@ -177,12 +175,11 @@ async def get_course_meta(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add tasks to the list
|
# Add tasks to the list
|
||||||
tasks.append(get_authors())
|
|
||||||
tasks.append(get_chapters())
|
tasks.append(get_chapters())
|
||||||
tasks.append(get_trail())
|
tasks.append(get_trail())
|
||||||
|
|
||||||
# Run all tasks concurrently
|
# Run all tasks concurrently
|
||||||
author_results, chapters, trail = await asyncio.gather(*tasks)
|
chapters, trail = await asyncio.gather(*tasks)
|
||||||
|
|
||||||
# Convert to AuthorWithRole objects
|
# Convert to AuthorWithRole objects
|
||||||
authors = [
|
authors = [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue