You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
3.7 KiB
75 lines
3.7 KiB
# backend/apps/hadis/management/commands/seed_hadis_chains.py
|
|
|
|
import random
|
|
from django.core.management.base import BaseCommand
|
|
from django.db import transaction
|
|
from apps.hadis.models import Hadis, Transmitters, HadisTransmitter, NarratorLayer, TransmitterReliability
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Seeds random transmission chains (HadisTransmitter) for all existing Hadiths.'
|
|
|
|
def handle(self, *args, **options):
|
|
self.stdout.write(self.style.WARNING("Starting to seed random transmission chains..."))
|
|
|
|
# دریافت تمام دیتاهای پایه
|
|
hadiths = list(Hadis.objects.all())
|
|
narrators = list(Transmitters.objects.all())
|
|
layers = list(NarratorLayer.objects.all())
|
|
reliabilities = list(TransmitterReliability.objects.all())
|
|
|
|
# بررسی وجود دیتای کافی
|
|
if not hadiths:
|
|
self.stdout.write(self.style.ERROR("No Hadiths found. Please seed Hadiths first."))
|
|
return
|
|
|
|
if len(narrators) < 4:
|
|
self.stdout.write(self.style.ERROR("Not enough Transmitters found. Please add at least 4 narrators."))
|
|
return
|
|
|
|
# پاک کردن تمام زنجیرههای روایی قبلی برای جلوگیری از خطای Unique Constraint
|
|
self.stdout.write("Clearing old transmission chains...")
|
|
HadisTransmitter.objects.all().delete()
|
|
|
|
links_to_create = []
|
|
|
|
# ساخت زنجیرهها
|
|
for hadis in hadiths:
|
|
# هر حدیث بین 2 تا 3 لایه/زنجیره (Chain) داشته باشد
|
|
num_chains = random.randint(2, 3)
|
|
|
|
for chain_idx in range(num_chains):
|
|
# هر زنجیره بین 4 تا 6 راوی داشته باشد
|
|
num_narrators = random.randint(4, min(6, len(narrators)))
|
|
|
|
# انتخاب رندوم چند راوی برای این زنجیره بدون تکرار
|
|
chain_narrators = random.sample(narrators, num_narrators)
|
|
|
|
for order_idx, narrator in enumerate(chain_narrators):
|
|
|
|
# انتخاب رندوم لایه و وضعیت (اگر در دیتابیس وجود داشته باشند)
|
|
random_layer = random.choice(layers) if layers else None
|
|
random_status = random.choice(reliabilities) if reliabilities else None
|
|
|
|
link = HadisTransmitter(
|
|
hadis=hadis,
|
|
transmitter=narrator,
|
|
chain_index=chain_idx,
|
|
order=order_idx, # ترتیب قرارگیری راوی در این زنجیره
|
|
narrator_layer=random_layer,
|
|
status=random_status,
|
|
is_gap=random.choice([True, False, False, False]) # احتمال کم برای گپ (انقطاع سند)
|
|
)
|
|
links_to_create.append(link)
|
|
|
|
# ذخیره دستهجمعی (Bulk Create) برای پرفورمنس بسیار بالاتر
|
|
with transaction.atomic():
|
|
# برای جلوگیری از محدودیت حافظه، در دستههای 1000 تایی ذخیره میکنیم
|
|
batch_size = 1000
|
|
for i in range(0, len(links_to_create), batch_size):
|
|
HadisTransmitter.objects.bulk_create(links_to_create[i:i + batch_size])
|
|
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f"\n🎉 Successfully created {len(links_to_create)} random narrator links across {len(hadiths)} Hadiths!"
|
|
)
|
|
)
|