Files
site/WESP_REL/migrations/versions/0015_lab_component_nutrient_value.py
T
2026-07-17 12:57:18 +03:00

87 lines
2.5 KiB
Python

"""lab_component_nutrient_value: полная матрица показателей (EAV).
Revision ID: lab_component_nutrient_value
Revises: drop_lab_calculation_run
Create Date: 2026-06-08
"""
from __future__ import annotations
import uuid
import sqlalchemy as sa
from alembic import op
from app.lab.models import LabComponentNutrientValue
revision = "lab_component_nutrient_value"
down_revision = "drop_lab_calculation_run"
branch_labels = None
depends_on = None
# 8 колонок lab_component_nutrients → заголовки FUTTERPLUS
_SUMMARY_TO_HEADER = {
"crude_protein": "Сыр. Протеин",
"usp": "уСП",
"bra": "БРА",
"nel_cattle": "ЧЭЛ- КРС",
"oe_cattle": "ОЭ-КРС",
"ndf": "Сырая клетч",
"structural_fiber": "Структур клетч",
"crude_fat": "Сырой жир",
}
def _migrate_summary_to_eav(bind) -> None:
insp = sa.inspect(bind)
if "lab_component_nutrients" not in insp.get_table_names():
return
rows = bind.execute(
sa.text(
"""
SELECT component_id, crude_protein, usp, bra, nel_cattle,
oe_cattle, ndf, structural_fiber, crude_fat
FROM lab_component_nutrients
"""
)
).fetchall()
col_order = list(_SUMMARY_TO_HEADER.keys())
for row in rows:
comp_id = row[0]
for i, header in enumerate(_SUMMARY_TO_HEADER.values()):
val = row[i + 1]
if val is None:
continue
bind.execute(
sa.text(
"""
INSERT INTO lab_component_nutrient_value
(id, component_id, nutrient_key, value)
VALUES (:id, :component_id, :nutrient_key, :value)
ON CONFLICT(component_id, nutrient_key) DO UPDATE SET value = excluded.value
"""
),
{
"id": str(uuid.uuid4()),
"component_id": comp_id,
"nutrient_key": header,
"value": val,
},
)
def upgrade(**kw) -> None:
if kw.get("tag") == "reports":
return
bind = op.get_bind()
LabComponentNutrientValue.__table__.create(bind, checkfirst=True)
_migrate_summary_to_eav(bind)
def downgrade(**kw) -> None:
if kw.get("tag") == "reports":
return
bind = op.get_bind()
if "lab_component_nutrient_value" in sa.inspect(bind).get_table_names():
op.drop_table("lab_component_nutrient_value")