Skip to content

Commit bede582

Browse files
committed
Optimize content status count queries for projects
Refactored content statistics queries in dashboard routes to use a single optimized database query via db_service.get_content_counts_by_status. The new implementation reduces multiple queries to a single grouped query, improving performance when retrieving content status counts for projects.
1 parent 23be5eb commit bede582

2 files changed

Lines changed: 27 additions & 32 deletions

File tree

app/routes/dashboard.py

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -425,13 +425,8 @@ async def project_content(project_id):
425425
page=page, per_page=25, error_out=False
426426
)
427427

428-
# Get total project statistics (not just current page)
429-
total_stats = {
430-
'total': Content.query.filter_by(project_id=project.id).count(),
431-
'approved': Content.query.filter_by(project_id=project.id, status='approved').count(),
432-
'rejected': Content.query.filter_by(project_id=project.id, status='rejected').count(),
433-
'flagged': Content.query.filter_by(project_id=project.id, status='flagged').count(),
434-
}
428+
# Get total project statistics (not just current page) - optimized single query
429+
total_stats = await db_service.get_content_counts_by_status(project.id)
435430

436431
return render_template('dashboard/content.html',
437432
project=project,
@@ -537,14 +532,12 @@ async def project_settings(project_id):
537532
flash('You do not have access to this project', 'error')
538533
return redirect(url_for('dashboard.projects'))
539534

540-
# Get comprehensive stats
541-
total_content = Content.query.filter_by(project_id=project.id).count()
542-
approved_content = Content.query.filter_by(
543-
project_id=project.id, status='approved').count()
544-
rejected_content = Content.query.filter_by(
545-
project_id=project.id, status='rejected').count()
546-
flagged_content = Content.query.filter_by(
547-
project_id=project.id, status='flagged').count()
535+
# Get comprehensive stats - optimized single query for content counts
536+
content_counts = await db_service.get_content_counts_by_status(project.id)
537+
total_content = content_counts.get('total', 0)
538+
approved_content = content_counts.get('approved', 0)
539+
rejected_content = content_counts.get('rejected', 0)
540+
flagged_content = content_counts.get('flagged', 0)
548541
rules_count = ModerationRule.query.filter_by(project_id=project.id).count()
549542
api_keys_count = APIKey.query.filter_by(project_id=project.id).count()
550543

app/services/database_service.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -856,27 +856,29 @@ def _get_user():
856856

857857
# Content Query Operations
858858
async def get_content_counts_by_status(self, project_id: str) -> Dict[str, int]:
859-
"""Get content counts by moderation status"""
859+
"""Get content counts by moderation status - optimized single query"""
860860
def _get_counts():
861-
total = Content.query.filter_by(project_id=project_id).count()
862-
approved = Content.query.filter_by(
863-
project_id=project_id, status='approved').count()
864-
rejected = Content.query.filter_by(
865-
project_id=project_id, status='rejected').count()
866-
flagged = Content.query.filter_by(
867-
project_id=project_id, status='flagged').count()
868-
pending = Content.query.filter_by(
869-
project_id=project_id, status='pending').count()
870-
error = Content.query.filter_by(
871-
project_id=project_id, status='error').count()
861+
# Use GROUP BY to get all counts in a single query
862+
status_counts = db.session.query(
863+
Content.status,
864+
func.count(Content.id).label('count')
865+
).filter(
866+
Content.project_id == project_id
867+
).group_by(Content.status).all()
868+
869+
# Convert to dictionary
870+
counts = {status: count for status, count in status_counts}
871+
872+
# Calculate total from the status counts
873+
total = sum(counts.values())
872874

873875
return {
874876
'total': total,
875-
'approved': approved,
876-
'rejected': rejected,
877-
'flagged': flagged,
878-
'pending': pending,
879-
'error': error
877+
'approved': counts.get('approved', 0),
878+
'rejected': counts.get('rejected', 0),
879+
'flagged': counts.get('flagged', 0),
880+
'pending': counts.get('pending', 0),
881+
'error': counts.get('error', 0)
880882
}
881883

882884
return await self._safe_execute(_get_counts) or {

0 commit comments

Comments
 (0)