netx/netx_api/models.py
oliver ac1f573508 Remove UME equipment-holder table; inventory is NE-only
Drop ume_inventory_equipment_holder on startup; remove ORM model and sync/reconcile paths. Sync status API/UI no longer expose deleted_inventory_holders. Nested holder data remains in ne raw_json if UME returns it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 18:48:45 +08:00

208 lines
12 KiB
Python

from __future__ import annotations
from datetime import datetime
from uuid import uuid4
from sqlalchemy import DateTime, ForeignKey, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .db import Base
class AlarmBatch(Base):
__tablename__ = "alarm_batches"
batch_id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: uuid4().hex)
source_file: Mapped[str] = mapped_column(String(512))
parser_version: Mapped[str] = mapped_column(String(64), default="zte_alarm_monitor_v1")
dict_version: Mapped[str] = mapped_column(String(64), default="v1")
total_rows: Mapped[int] = mapped_column(Integer, default=0)
success_rows: Mapped[int] = mapped_column(Integer, default=0)
failed_rows: Mapped[int] = mapped_column(Integer, default=0)
status: Mapped[str] = mapped_column(String(32), default="done")
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
alarms: Mapped[list["AlarmNorm"]] = relationship(back_populates="batch")
errors: Mapped[list["ImportErrorRow"]] = relationship(back_populates="batch")
class AlarmNorm(Base):
__tablename__ = "alarms_norm"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
batch_id: Mapped[str] = mapped_column(ForeignKey("alarm_batches.batch_id"), index=True)
row_no: Mapped[int] = mapped_column(Integer)
alarm_time: Mapped[datetime] = mapped_column(DateTime, index=True)
clear_time: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
severity_raw: Mapped[str] = mapped_column(String(64), default="")
severity_norm: Mapped[str] = mapped_column(String(32), index=True, default="unknown")
ne_name: Mapped[str] = mapped_column(String(256), default="", index=True)
ne_id: Mapped[str] = mapped_column(String(128), default="", index=True)
site_name: Mapped[str] = mapped_column(String(256), default="")
alarm_code: Mapped[str] = mapped_column(String(256), default="", index=True)
# NOTE: historically we stored `alarm_name` separately, but for ZTE Alarm Monitor exports
# "Alarm Code Name" is a single column. We keep the DB column for backward compatibility,
# but APIs/UI are unified on `alarm_code`.
alarm_name: Mapped[str] = mapped_column(String(512), default="")
description: Mapped[str] = mapped_column(Text, default="")
ack_state: Mapped[str] = mapped_column(String(64), default="")
clear_state: Mapped[str] = mapped_column(String(64), default="")
relevancy: Mapped[str] = mapped_column(String(128), default="")
l3vpn_peer_ne: Mapped[str] = mapped_column(String(256), default="")
service: Mapped[str] = mapped_column(String(256), default="")
affected_client_service_number: Mapped[int] = mapped_column(Integer, default=0)
intermittence_count: Mapped[int] = mapped_column(Integer, default=0)
me_level: Mapped[str] = mapped_column(String(128), default="")
vendor: Mapped[str] = mapped_column(String(64), default="ZTE")
source_type: Mapped[str] = mapped_column(String(64), default="gateway_export_excel")
source_file: Mapped[str] = mapped_column(String(512), default="")
raw_json: Mapped[str] = mapped_column(Text, default="{}")
batch: Mapped[AlarmBatch] = relationship(back_populates="alarms")
class ImportErrorRow(Base):
__tablename__ = "import_errors"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
batch_id: Mapped[str] = mapped_column(ForeignKey("alarm_batches.batch_id"), index=True)
row_no: Mapped[int] = mapped_column(Integer)
reason: Mapped[str] = mapped_column(String(512))
raw_json: Mapped[str] = mapped_column(Text, default="{}")
batch: Mapped[AlarmBatch] = relationship(back_populates="errors")
class ImportJob(Base):
__tablename__ = "import_jobs"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
kind: Mapped[str] = mapped_column(String(32), index=True) # alarms/logs/config
file_name: Mapped[str] = mapped_column(String(512), default="")
batch_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ok: Mapped[int] = mapped_column(Integer, default=1) # 1 ok, 0 error
summary: Mapped[str] = mapped_column(String(1024), default="")
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)
class AiAnalyzeHistory(Base):
__tablename__ = "ai_analyze_history"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
analysis_request_id: Mapped[str] = mapped_column(String(128), default="", index=True)
batch_id: Mapped[str] = mapped_column(String(64), default="", index=True)
question: Mapped[str] = mapped_column(Text, default="")
filters_json: Mapped[str] = mapped_column(Text, default="{}")
ok: Mapped[int] = mapped_column(Integer, default=1) # 1 ok, 0 error
answer: Mapped[str] = mapped_column(Text, default="")
error: Mapped[str] = mapped_column(Text, default="")
evidence_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)
class UmeSyncJob(Base):
__tablename__ = "ume_sync_jobs"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
domain: Mapped[str] = mapped_column(String(32), index=True, default="inventory")
status: Mapped[str] = mapped_column(String(32), index=True, default="running")
trigger_mode: Mapped[str] = mapped_column(String(32), default="manual")
started_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)
ended_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
pulled_count: Mapped[int] = mapped_column(Integer, default=0)
inserted_count: Mapped[int] = mapped_column(Integer, default=0)
updated_count: Mapped[int] = mapped_column(Integer, default=0)
error_message: Mapped[str] = mapped_column(String(1024), default="")
details_json: Mapped[str] = mapped_column(Text, default="{}")
class UmeAlarmBatch(Base):
__tablename__ = "ume_alarm_batches"
batch_id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: uuid4().hex)
kind: Mapped[str] = mapped_column(String(16), index=True, default="current") # current/history
status: Mapped[str] = mapped_column(String(32), default="done")
total_rows: Mapped[int] = mapped_column(Integer, default=0)
success_rows: Mapped[int] = mapped_column(Integer, default=0)
failed_rows: Mapped[int] = mapped_column(Integer, default=0)
started_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
ended_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
error_message: Mapped[str] = mapped_column(String(1024), default="")
raw_json: Mapped[str] = mapped_column(Text, default="{}")
class UmeInventoryNE(Base):
__tablename__ = "ume_inventory_ne"
ne_id: Mapped[str] = mapped_column(String(128), primary_key=True, comment="网元uuid")
ne_name: Mapped[str] = mapped_column(String(256), default="", index=True, comment="资源名称")
user_label: Mapped[str] = mapped_column(String(256), default="", index=True, comment="用户标签")
ip_address: Mapped[str] = mapped_column(String(128), default="", index=True, comment="网元IPv4地址")
ipv6_address: Mapped[str] = mapped_column(String(128), default="", index=True, comment="IPv6地址")
ne_type: Mapped[str] = mapped_column(String(128), default="", comment="网元类型")
device_level: Mapped[str] = mapped_column(String(64), default="", comment="网元层次")
host_name: Mapped[str] = mapped_column(String(256), default="", comment="主机名称")
location: Mapped[str] = mapped_column(String(512), default="")
hardware_version: Mapped[str] = mapped_column(String(128), default="", comment="硬件版本")
loopback: Mapped[str] = mapped_column(String(128), default="", comment="业务环回IP(IPv4)")
consistent_state: Mapped[str] = mapped_column(String(64), default="", comment="数据一致性状态")
interface_version: Mapped[str] = mapped_column(String(128), default="", comment="网元接口版本号")
mac: Mapped[str] = mapped_column(String(128), default="", comment="设备机架MAC地址")
admin_status: Mapped[str] = mapped_column(String(64), default="", comment="管理状态")
address_type: Mapped[str] = mapped_column(String(64), default="", comment="管理地址类型(1:IPv4,2:IPv6)")
connection_status: Mapped[str] = mapped_column(String(64), default="", comment="连接状态")
maintain_status: Mapped[str] = mapped_column(String(64), default="", comment="工程状态")
net_mask: Mapped[str] = mapped_column(String(128), default="", comment="管理IPv4掩码")
create_time: Mapped[str] = mapped_column(String(64), default="")
creator: Mapped[str] = mapped_column(String(128), default="")
vendor: Mapped[str] = mapped_column(String(64), default="ZTE", comment="网元提供商")
source_type: Mapped[str] = mapped_column(String(64), default="ume_restconf")
first_seen_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
last_seen_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)
raw_json: Mapped[str] = mapped_column(Text, default="{}")
class UmeAlarmCurrent(Base):
__tablename__ = "ume_alarms_current"
alarm_key: Mapped[str] = mapped_column(String(256), primary_key=True)
ne_id: Mapped[str] = mapped_column(String(128), default="", index=True)
object_name: Mapped[str] = mapped_column(String(512), default="", index=True)
event_type: Mapped[str] = mapped_column(String(128), default="")
native_probable_cause: Mapped[str] = mapped_column(String(256), default="")
perceived_severity: Mapped[str] = mapped_column(String(64), default="", index=True)
is_cleared: Mapped[str] = mapped_column(String(16), default="", index=True)
time_created: Mapped[str] = mapped_column(String(64), default="", index=True)
root_cause_alarm_indication: Mapped[str] = mapped_column(String(32), default="")
first_seen_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
last_seen_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)
raw_json: Mapped[str] = mapped_column(Text, default="{}")
class UmeAlarmHistory(Base):
__tablename__ = "ume_alarms_history"
alarm_key: Mapped[str] = mapped_column(String(256), primary_key=True)
ne_id: Mapped[str] = mapped_column(String(128), default="", index=True)
object_name: Mapped[str] = mapped_column(String(512), default="", index=True)
event_type: Mapped[str] = mapped_column(String(128), default="")
native_probable_cause: Mapped[str] = mapped_column(String(256), default="")
perceived_severity: Mapped[str] = mapped_column(String(64), default="", index=True)
is_cleared: Mapped[str] = mapped_column(String(16), default="", index=True)
time_created: Mapped[str] = mapped_column(String(64), default="", index=True)
root_cause_alarm_indication: Mapped[str] = mapped_column(String(32), default="")
first_seen_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
last_seen_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)
raw_json: Mapped[str] = mapped_column(Text, default="{}")
class UmeTokenCache(Base):
__tablename__ = "ume_token_cache"
cache_key: Mapped[str] = mapped_column(String(256), primary_key=True)
token: Mapped[str] = mapped_column(Text, default="")
expires_at_epoch_s: Mapped[int] = mapped_column(Integer, default=0)
lock_owner: Mapped[str] = mapped_column(String(128), default="", index=True)
lock_expires_at_epoch_s: Mapped[int] = mapped_column(Integer, default=0, index=True)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)