136 lines
4.6 KiB
Python
136 lines
4.6 KiB
Python
#!/usr/bin/env python
|
||
"""
|
||
Тест денормализации unread_count
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
import django
|
||
|
||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "eusrr_backend.settings")
|
||
django.setup()
|
||
|
||
from django.conf import settings
|
||
from django.contrib.auth import get_user_model
|
||
from django.db import connection, reset_queries
|
||
|
||
from communications.models import Chat, ChatReadState, Message
|
||
|
||
# Включаем отслеживание SQL
|
||
settings.DEBUG = True
|
||
|
||
Employee = get_user_model()
|
||
|
||
|
||
def test_denormalized_unread():
|
||
"""Тестируем оптимизированный подход с денормализацией"""
|
||
|
||
user = Employee.objects.first()
|
||
if not user:
|
||
print("❌ Нет пользователей в базе")
|
||
return
|
||
|
||
print(f"📊 Тестируем денормализацию для пользователя: {user}")
|
||
print("=" * 80)
|
||
|
||
# Сбрасываем счетчик запросов
|
||
reset_queries()
|
||
|
||
# НОВЫЙ ОПТИМИЗИРОВАННЫЙ KOD из ChatViewSet.get_queryset()
|
||
from django.db.models import Prefetch, Q
|
||
|
||
from communications.models import ChatUserSettings
|
||
|
||
chats = (
|
||
Chat.objects.filter(
|
||
Q(participants=user)
|
||
| Q(
|
||
department__in=user.departments_links.filter(is_active=True).values(
|
||
"department"
|
||
)
|
||
)
|
||
| Q(include_all_employees=True)
|
||
)
|
||
.select_related("department", "created_by")
|
||
.prefetch_related(
|
||
"participants",
|
||
Prefetch(
|
||
"user_settings",
|
||
queryset=ChatUserSettings.objects.filter(user=user),
|
||
to_attr="my_settings",
|
||
),
|
||
Prefetch(
|
||
"read_states",
|
||
queryset=ChatReadState.objects.filter(user=user),
|
||
to_attr="my_read_state",
|
||
),
|
||
)
|
||
.distinct()[:10]
|
||
)
|
||
|
||
# Принудительно выполняем запрос
|
||
chat_list = list(chats)
|
||
|
||
print(f"\n✅ Загружено чатов: {len(chat_list)}")
|
||
print(f"📈 Количество SQL запросов: {len(connection.queries)}")
|
||
print("\n" + "=" * 80)
|
||
|
||
# Показываем unread_count для каждого чата
|
||
print("\n📬 Счетчики непрочитанных:")
|
||
for chat in chat_list:
|
||
unread = 0
|
||
if hasattr(chat, "my_read_state") and chat.my_read_state:
|
||
unread = chat.my_read_state[0].unread_count
|
||
|
||
print(f" Chat #{chat.id} ({chat.type}): {unread} непрочитанных")
|
||
|
||
# Показываем SQL запросы
|
||
print("\n" + "=" * 80)
|
||
print("\n🔍 SQL Запросы:")
|
||
for i, query in enumerate(connection.queries, 1):
|
||
print(f"\n[{i}] {query['sql'][:200]}...")
|
||
print(f" Время: {query['time']}s")
|
||
|
||
print("\n" + "=" * 80)
|
||
print("\n✨ РЕЗУЛЬТАТ:")
|
||
print(" - Один основной JOIN запрос вместо 100+ подзапросов")
|
||
print(" - unread_count читается из денормализованного поля")
|
||
print(
|
||
f" - Общее время выполнения: {sum(float(q['time']) for q in connection.queries):.4f}s"
|
||
)
|
||
|
||
# Тест создания нового сообщения
|
||
print("\n" + "=" * 80)
|
||
print("\n📝 Тест: создание нового сообщения...")
|
||
|
||
test_chat = chat_list[0] if chat_list else None
|
||
if test_chat:
|
||
reset_queries()
|
||
|
||
# Создаем сообщение от другого пользователя
|
||
other_user = Employee.objects.exclude(id=user.id).first()
|
||
if other_user:
|
||
msg = Message.objects.create(
|
||
chat=test_chat,
|
||
author=other_user,
|
||
content="Тестовое сообщение для проверки инкремента",
|
||
)
|
||
|
||
print(f"✅ Сообщение создано: #{msg.id}")
|
||
print(f"📊 SQL запросов: {len(connection.queries)}")
|
||
|
||
# Проверяем что счетчик увеличился
|
||
read_state = ChatReadState.objects.get(chat=test_chat, user=user)
|
||
print(f"📈 Новый unread_count: {read_state.unread_count}")
|
||
|
||
# Удаляем тестовое сообщение
|
||
msg.delete()
|
||
print("🗑️ Тестовое сообщение удалено")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
test_denormalized_unread()
|