fix --> sync livestocks with table ExcelLivestocks
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
from datetime import datetime
|
||||
|
||||
import jdatetime
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.herd.models import Herd
|
||||
from apps.livestock.models import (
|
||||
LiveStock,
|
||||
LiveStockSpecies,
|
||||
ExcelLiveStocks
|
||||
)
|
||||
|
||||
BATCH_SIZE = 100
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Import livestock from ExcelLiveStocks into LiveStock using bulk_create"
|
||||
|
||||
def normalize_herd_code(self, value, length=10):
|
||||
if value is None:
|
||||
return None
|
||||
return str(value).strip().zfill(length)
|
||||
|
||||
def parse_jalali_datetime(self, date_str: str):
|
||||
if not date_str:
|
||||
return None
|
||||
|
||||
year, month, day = map(int, date_str.split('/'))
|
||||
|
||||
# jalali → gregorian (date)
|
||||
g_date = jdatetime.date(year, month, day).togregorian()
|
||||
|
||||
# date → naive datetime
|
||||
naive_dt = datetime.combine(g_date, datetime.min.time())
|
||||
|
||||
# naive → aware (VERY IMPORTANT)
|
||||
return timezone.make_aware(naive_dt)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
qs = ExcelLiveStocks.objects.all()
|
||||
|
||||
if not qs.exists():
|
||||
self.stdout.write(self.style.WARNING("No records to import"))
|
||||
return
|
||||
|
||||
# ---------- preload lookups ----------
|
||||
herd_map = {
|
||||
h.code: h
|
||||
for h in Herd.objects.all()
|
||||
}
|
||||
|
||||
species_map = {
|
||||
s.name.strip(): s
|
||||
for s in LiveStockSpecies.objects.all()
|
||||
}
|
||||
|
||||
livestocks_to_create = []
|
||||
processed_ids = []
|
||||
|
||||
created_count = 0
|
||||
skipped = 0
|
||||
|
||||
self.stdout.write("Starting import...")
|
||||
|
||||
with transaction.atomic():
|
||||
for row in qs.iterator(chunk_size=BATCH_SIZE):
|
||||
herd = herd_map.get(self.normalize_herd_code(row.herd_code))
|
||||
# print(self.normalize_herd_code(row.herd_code))
|
||||
if not herd:
|
||||
# print("herd")
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
# species cache / create
|
||||
species_name = (row.species or "").strip()
|
||||
if not species_name:
|
||||
# print("species")
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
species = species_map.get(species_name)
|
||||
if not species:
|
||||
species = LiveStockSpecies.objects.create(
|
||||
name=species_name
|
||||
)
|
||||
species_map[species_name] = species
|
||||
|
||||
livestocks_to_create.append(
|
||||
LiveStock(
|
||||
herd=herd,
|
||||
species=species,
|
||||
gender=self.map_gender(row.gender),
|
||||
birthdate=self.parse_jalali_datetime(row.birthdate),
|
||||
)
|
||||
)
|
||||
processed_ids.append(row.id)
|
||||
|
||||
if len(livestocks_to_create) >= BATCH_SIZE:
|
||||
print("-----------------------------CREATE------------------------------------")
|
||||
print(livestocks_to_create)
|
||||
LiveStock.objects.bulk_create(
|
||||
livestocks_to_create,
|
||||
batch_size=BATCH_SIZE
|
||||
)
|
||||
created_count += len(livestocks_to_create)
|
||||
livestocks_to_create.clear()
|
||||
break
|
||||
|
||||
# flush remaining
|
||||
if livestocks_to_create:
|
||||
LiveStock.objects.bulk_create(
|
||||
livestocks_to_create,
|
||||
batch_size=BATCH_SIZE
|
||||
)
|
||||
created_count += len(livestocks_to_create)
|
||||
|
||||
# mark excel rows as archived
|
||||
# ExcelLiveStocks.objects.filter(
|
||||
# id__in=processed_ids
|
||||
# ).update(archive=True)
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
f"Import finished. Created: {created_count}, Skipped: {skipped}"
|
||||
))
|
||||
|
||||
@staticmethod
|
||||
def map_gender(value):
|
||||
if not value:
|
||||
return 1
|
||||
value = value.strip().lower()
|
||||
if value in ['female', 'f', 'ماده']:
|
||||
return 2
|
||||
return 1
|
||||
|
||||
@staticmethod
|
||||
def parse_date(value):
|
||||
if not value:
|
||||
return None
|
||||
try:
|
||||
return datetime.strptime(value, '%Y/%m/%d')
|
||||
except Exception:
|
||||
return None
|
||||
Reference in New Issue
Block a user