Files
production-analytics/src/production_analytics/service/postgres_material_efficiency.py
T

72 lines
3.1 KiB
Python

"""Immutable PostgreSQL history of feedback-aligned KPI points."""
from typing import Protocol
import psycopg
from production_analytics.calculations.config import finite_number
from production_analytics.service.material_efficiency import MaterialEfficiencySnapshot
from production_analytics.service.postgres_material import PostgresSettings
class MaterialEfficiencyWriter(Protocol):
def write(self, snapshot: MaterialEfficiencySnapshot) -> bool: ...
class PostgresMaterialEfficiencyWriter:
def __init__(self, settings: PostgresSettings) -> None:
self.settings = settings
def write(self, snapshot: MaterialEfficiencySnapshot) -> bool:
for name in ("erp_feedback_timestamp", "material_snapshot_timestamp"):
if getattr(snapshot, name).utcoffset() is None:
raise ValueError(f"{name} must be timezone-aware")
for name in (
"good_quantity_m2",
"material_consumption_kg",
"material_consumption_kg_per_m2",
"material_consumption_g_per_m2",
):
finite_number(getattr(snapshot, name), name)
if snapshot.nominal_width_m is not None:
finite_number(snapshot.nominal_width_m, "nominal_width_m")
# Context exit commits/rolls back and closes; later cycles reconnect after outages.
with psycopg.connect(
host=self.settings.host,
port=self.settings.port,
dbname=self.settings.dbname,
user=self.settings.user,
password=self.settings.password,
connect_timeout=10,
options="-c statement_timeout=10000",
) as connection:
row = connection.execute(
"""INSERT INTO material_efficiency_snapshots (
erp_feedback_timestamp, material_snapshot_timestamp, calculation_id,
machine_id, workplace, erp_production_order, enlyze_production_order,
article_number, article_description, nominal_width_m, good_quantity_m2,
material_consumption_kg, material_consumption_kg_per_m2,
material_consumption_g_per_m2
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (calculation_id, machine_id, enlyze_production_order,
erp_feedback_timestamp) DO NOTHING
RETURNING 1""",
(
snapshot.erp_feedback_timestamp,
snapshot.material_snapshot_timestamp,
snapshot.calculation_id,
snapshot.machine_id,
snapshot.workplace,
snapshot.erp_production_order,
snapshot.enlyze_production_order,
snapshot.article_number,
snapshot.article_description,
snapshot.nominal_width_m,
snapshot.good_quantity_m2,
snapshot.material_consumption_kg,
snapshot.material_consumption_kg_per_m2,
snapshot.material_consumption_g_per_m2,
),
).fetchone()
return row is not None