mirror of
https://github.com/hansjone/netx.git
synced 2026-10-18 19:43:15 +08:00
Fix port-traffic create 500 from legacy task_id NOT NULL.
Brownfield tables still require task_id while ORM only wrote device_id; mirror both columns on write and relax the leftover constraint. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
ce835dde3d
commit
d26e4ca2fc
2 changed files with 61 additions and 15 deletions
|
|
@ -3,13 +3,20 @@ from __future__ import annotations
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from sqlalchemy import BigInteger, Boolean, DateTime, Float, ForeignKey, Integer, LargeBinary, String, Text, UniqueConstraint
|
from sqlalchemy import BigInteger, Boolean, DateTime, Float, ForeignKey, Integer, LargeBinary, String, Text, UniqueConstraint, event
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from ..db import Base
|
from ..db import Base
|
||||||
from ..timeutil import utcnow_naive
|
from ..timeutil import utcnow_naive
|
||||||
from ._types import JsonType as _JsonType
|
from ._types import JsonType as _JsonType
|
||||||
|
|
||||||
|
|
||||||
|
def _mirror_device_task_id(target: object) -> None:
|
||||||
|
"""Keep legacy task_id column aligned with device_id (brownfield NOT NULL)."""
|
||||||
|
did = str(getattr(target, "device_id", None) or getattr(target, "task_id", None) or "")
|
||||||
|
target.device_id = did # type: ignore[attr-defined]
|
||||||
|
target.task_id = did # type: ignore[attr-defined]
|
||||||
|
|
||||||
class PortTrafficDevice(Base):
|
class PortTrafficDevice(Base):
|
||||||
"""Per-NE port traffic monitoring config (device-centric)."""
|
"""Per-NE port traffic monitoring config (device-centric)."""
|
||||||
|
|
||||||
|
|
@ -49,18 +56,12 @@ class PortTrafficSeries(Base):
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: uuid4().hex)
|
id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: uuid4().hex)
|
||||||
device_id: Mapped[str] = mapped_column(String(64), default="", index=True)
|
device_id: Mapped[str] = mapped_column(String(64), default="", index=True)
|
||||||
|
# Legacy column retained for brownfield DBs that still enforce NOT NULL task_id.
|
||||||
|
task_id: Mapped[str] = mapped_column(String(64), default="")
|
||||||
title: Mapped[str] = mapped_column(String(256), default="")
|
title: Mapped[str] = mapped_column(String(256), default="")
|
||||||
status: Mapped[str] = mapped_column(String(32), default="active", index=True) # active|disabled
|
status: Mapped[str] = mapped_column(String(32), default="active", index=True) # active|disabled
|
||||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=utcnow_naive)
|
created_at: Mapped[datetime] = mapped_column(DateTime, default=utcnow_naive)
|
||||||
|
|
||||||
@property
|
|
||||||
def task_id(self) -> str:
|
|
||||||
return str(self.device_id or "")
|
|
||||||
|
|
||||||
@task_id.setter
|
|
||||||
def task_id(self, value: str) -> None:
|
|
||||||
self.device_id = str(value or "")
|
|
||||||
|
|
||||||
|
|
||||||
class PortTrafficTarget(Base):
|
class PortTrafficTarget(Base):
|
||||||
"""Monitored interface under a device monitoring config."""
|
"""Monitored interface under a device monitoring config."""
|
||||||
|
|
@ -69,6 +70,8 @@ class PortTrafficTarget(Base):
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: uuid4().hex)
|
id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: uuid4().hex)
|
||||||
device_id: Mapped[str] = mapped_column(String(64), default="", index=True)
|
device_id: Mapped[str] = mapped_column(String(64), default="", index=True)
|
||||||
|
# Legacy column retained for brownfield DBs that still enforce NOT NULL task_id.
|
||||||
|
task_id: Mapped[str] = mapped_column(String(64), default="")
|
||||||
series_id: Mapped[str] = mapped_column(String(64), default="", index=True)
|
series_id: Mapped[str] = mapped_column(String(64), default="", index=True)
|
||||||
source: Mapped[str] = mapped_column(String(32), default="managed", index=True)
|
source: Mapped[str] = mapped_column(String(32), default="managed", index=True)
|
||||||
target_id: Mapped[str] = mapped_column(String(128), index=True) # NE id
|
target_id: Mapped[str] = mapped_column(String(128), index=True) # NE id
|
||||||
|
|
@ -83,13 +86,17 @@ class PortTrafficTarget(Base):
|
||||||
last_sample_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
last_sample_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=utcnow_naive)
|
created_at: Mapped[datetime] = mapped_column(DateTime, default=utcnow_naive)
|
||||||
|
|
||||||
@property
|
|
||||||
def task_id(self) -> str:
|
|
||||||
return str(self.device_id or "")
|
|
||||||
|
|
||||||
@task_id.setter
|
@event.listens_for(PortTrafficSeries, "before_insert")
|
||||||
def task_id(self, value: str) -> None:
|
@event.listens_for(PortTrafficSeries, "before_update")
|
||||||
self.device_id = str(value or "")
|
def _sync_series_task_id(mapper, connection, target) -> None: # noqa: ANN001
|
||||||
|
_mirror_device_task_id(target)
|
||||||
|
|
||||||
|
|
||||||
|
@event.listens_for(PortTrafficTarget, "before_insert")
|
||||||
|
@event.listens_for(PortTrafficTarget, "before_update")
|
||||||
|
def _sync_target_task_id(mapper, connection, target) -> None: # noqa: ANN001
|
||||||
|
_mirror_device_task_id(target)
|
||||||
|
|
||||||
|
|
||||||
class PortTrafficSample(Base):
|
class PortTrafficSample(Base):
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,27 @@ def ensure_port_traffic_series_schema(conn) -> None:
|
||||||
conn.exec_driver_sql(
|
conn.exec_driver_sql(
|
||||||
"ALTER TABLE port_traffic_series ADD COLUMN IF NOT EXISTS task_id VARCHAR(64) DEFAULT ''"
|
"ALTER TABLE port_traffic_series ADD COLUMN IF NOT EXISTS task_id VARCHAR(64) DEFAULT ''"
|
||||||
)
|
)
|
||||||
|
# Older installs created task_id as NOT NULL before the device-centric rename.
|
||||||
|
# Keep both columns populated and relax NOT NULL so ORM inserts that only set
|
||||||
|
# device_id (or only task_id) do not 500.
|
||||||
|
for sql in (
|
||||||
|
"""
|
||||||
|
UPDATE port_traffic_series
|
||||||
|
SET device_id = task_id
|
||||||
|
WHERE COALESCE(device_id, '') = '' AND COALESCE(task_id, '') <> ''
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
UPDATE port_traffic_series
|
||||||
|
SET task_id = device_id
|
||||||
|
WHERE COALESCE(task_id, '') = '' AND COALESCE(device_id, '') <> ''
|
||||||
|
""",
|
||||||
|
"ALTER TABLE port_traffic_series ALTER COLUMN task_id DROP NOT NULL",
|
||||||
|
"ALTER TABLE port_traffic_series ALTER COLUMN task_id SET DEFAULT ''",
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
conn.exec_driver_sql(sql)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
conn.exec_driver_sql(
|
conn.exec_driver_sql(
|
||||||
"CREATE INDEX IF NOT EXISTS ix_port_traffic_series_device_id ON port_traffic_series (device_id)"
|
"CREATE INDEX IF NOT EXISTS ix_port_traffic_series_device_id ON port_traffic_series (device_id)"
|
||||||
)
|
)
|
||||||
|
|
@ -79,6 +100,24 @@ def ensure_port_traffic_series_schema(conn) -> None:
|
||||||
conn.exec_driver_sql(
|
conn.exec_driver_sql(
|
||||||
"ALTER TABLE port_traffic_target ADD COLUMN IF NOT EXISTS task_id VARCHAR(64) DEFAULT ''"
|
"ALTER TABLE port_traffic_target ADD COLUMN IF NOT EXISTS task_id VARCHAR(64) DEFAULT ''"
|
||||||
)
|
)
|
||||||
|
for sql in (
|
||||||
|
"""
|
||||||
|
UPDATE port_traffic_target
|
||||||
|
SET device_id = task_id
|
||||||
|
WHERE COALESCE(device_id, '') = '' AND COALESCE(task_id, '') <> ''
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
UPDATE port_traffic_target
|
||||||
|
SET task_id = device_id
|
||||||
|
WHERE COALESCE(task_id, '') = '' AND COALESCE(device_id, '') <> ''
|
||||||
|
""",
|
||||||
|
"ALTER TABLE port_traffic_target ALTER COLUMN task_id DROP NOT NULL",
|
||||||
|
"ALTER TABLE port_traffic_target ALTER COLUMN task_id SET DEFAULT ''",
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
conn.exec_driver_sql(sql)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
conn.exec_driver_sql(
|
conn.exec_driver_sql(
|
||||||
"CREATE INDEX IF NOT EXISTS ix_port_traffic_target_series_id ON port_traffic_target (series_id)"
|
"CREATE INDEX IF NOT EXISTS ix_port_traffic_target_series_id ON port_traffic_target (series_id)"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue