91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
"""5 профилей норм для проверки математики рациона (строки 1–5 из data/seed/norms)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import csv
|
|
import logging
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
|
|
from app import db
|
|
from app.lab.commands.import_seed import _parse_min_max_groups, parse_norm_profile_row
|
|
from app.lab.seed_paths import norms_dir
|
|
from app.lab.models import LabAnimalProfile
|
|
from app.lab.services.profile_norms import save_norms_from_payload
|
|
from app.models.base import default_uuid
|
|
|
|
_log = logging.getLogger(__name__)
|
|
|
|
_MATH_SPECS: tuple[tuple[str, str, int, str], ...] = (
|
|
("DAIRY", "Нормы Дойн.csv", 1, "lab_math_dairy_01"),
|
|
("DAIRY", "Нормы Дойн.csv", 2, "lab_math_dairy_02"),
|
|
("DAIRY", "Нормы Дойн.csv", 3, "lab_math_dairy_03"),
|
|
("DAIRY", "Нормы Дойн.csv", 4, "lab_math_dairy_04"),
|
|
("DAIRY", "Нормы Дойн.csv", 5, "lab_math_dairy_05"),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class MathTestSeedStats:
|
|
created: int = 0
|
|
updated: int = 0
|
|
errors: list[str] = field(default_factory=list)
|
|
|
|
|
|
def _load_csv_row(csv_path: Path, external_no: int, ration_type: str) -> dict | None:
|
|
with csv_path.open(encoding="utf-8") as f:
|
|
rows = list(csv.reader(f))
|
|
if len(rows) < 8:
|
|
return None
|
|
groups = _parse_min_max_groups(rows[2], rows[3])
|
|
data_row = rows[5 + external_no]
|
|
|
|
eno = external_no
|
|
return parse_norm_profile_row(
|
|
data_row,
|
|
groups,
|
|
ration_type,
|
|
unmapped=set(),
|
|
profile_key_fn=lambda rt, _ext: f"lab_math_{rt.lower()}_{eno:02d}",
|
|
)
|
|
|
|
|
|
def seed_math_test_profiles(*, csv_dir: Path | None = None) -> MathTestSeedStats:
|
|
stats = MathTestSeedStats()
|
|
base = csv_dir or norms_dir()
|
|
|
|
for ration_type, filename, external_no, profile_key in _MATH_SPECS:
|
|
parsed = _load_csv_row(base / filename, external_no, ration_type)
|
|
if parsed is None:
|
|
stats.errors.append(f"Строка {external_no} не найдена в {filename}")
|
|
continue
|
|
|
|
profile = LabAnimalProfile.query.filter_by(profile_key=profile_key, is_deleted=False).first()
|
|
if profile is None:
|
|
profile = LabAnimalProfile(
|
|
id=default_uuid(),
|
|
profile_key=profile_key,
|
|
created_by="lab-math-test-seed",
|
|
)
|
|
db.session.add(profile)
|
|
stats.created += 1
|
|
else:
|
|
stats.updated += 1
|
|
|
|
profile.label = f"TEST математика #{external_no} — {parsed['label'][:48]}"
|
|
profile.ration_type = ration_type
|
|
profile.external_no = parsed["external_no"]
|
|
parsed["indicators"]["rnb"] = {"min": -10.0, "max": 20.0}
|
|
save_norms_from_payload(
|
|
profile,
|
|
{
|
|
"massKg": parsed["mass_kg"],
|
|
"externalNo": parsed["external_no"],
|
|
"indicators": parsed["indicators"],
|
|
},
|
|
)
|
|
|
|
db.session.commit()
|
|
_log.info("lab math test profiles: created=%s updated=%s", stats.created, stats.updated)
|
|
return stats
|