Files
InternalAuditInterprise/backend/app/ingest/adapters_r14.py
T

150 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""R14 适配器:云业务 / IDC 与新兴业务。
源明细:SrcCloudUsage / SrcIdcCabinet
映射到:Entity(CONTRACT, CUSTOMER) + MetricEvent
"""
from __future__ import annotations
import datetime as dt
import uuid
from sqlalchemy.orm import Session
from app.datahub.graph_repo import upsert_entity
from app.datahub.models import MetricEvent
from app.datahub.ontology import EntityType
from app.datahub.staging import SrcCloudUsage, SrcIdcCabinet
from app.ingest.base import BaseAdapter, IngestResult
from app.ingest.registry import register_adapter
@register_adapter
class CloudUsageAdapter(BaseAdapter):
"""SrcCloudUsage → Entity(CONTRACT) + MetricEvent(云资源用量时序)。"""
source_system = "BSS"
staging_table = "src_cloud_usage"
def ingest(
self,
session: Session,
data_version_id: uuid.UUID | None = None,
batch_size: int = 1000,
) -> IngestResult:
result = IngestResult()
query = session.query(SrcCloudUsage)
if data_version_id:
query = query.filter(SrcCloudUsage.data_version_id == data_version_id)
rows = query.limit(batch_size).all()
for row in rows:
try:
# 合同实体
upsert_entity(
session,
entity_type=EntityType.CONTRACT,
business_key=row.contract_no,
data_version_id=data_version_id,
)
# 客户实体(如有)
if row.customer_key:
upsert_entity(
session,
entity_type=EntityType.CUSTOMER,
business_key=row.customer_key,
data_version_id=data_version_id,
)
# 云资源用量事件
if row.usage_date:
event_time = dt.datetime.combine(
row.usage_date, dt.time.min, tzinfo=dt.timezone.utc
)
event = MetricEvent(
event_time=event_time,
subject_type="contract",
subject_key=row.contract_no,
metric_name="cloud_usage",
metric_value=row.actual_usage,
attributes={
"resource_type": row.resource_type,
"contracted_quota": row.contracted_quota,
"billed_usage": row.billed_usage,
"unit": row.unit,
"customer_key": row.customer_key,
},
data_version_id=data_version_id,
)
session.add(event)
result.metric_events.append(event)
result.row_count += 1
except Exception:
result.error_count += 1
return result
@register_adapter
class IdcCabinetAdapter(BaseAdapter):
"""SrcIdcCabinet → MetricEventIDC 机柜出租率/电力时序)。"""
source_system = "OSS"
staging_table = "src_idc_cabinet"
def ingest(
self,
session: Session,
data_version_id: uuid.UUID | None = None,
batch_size: int = 1000,
) -> IngestResult:
result = IngestResult()
query = session.query(SrcIdcCabinet)
if data_version_id:
query = query.filter(SrcIdcCabinet.data_version_id == data_version_id)
rows = query.limit(batch_size).all()
for row in rows:
try:
# 合同实体(如有)
if row.contract_no:
upsert_entity(
session,
entity_type=EntityType.CONTRACT,
business_key=row.contract_no,
data_version_id=data_version_id,
)
# IDC 出租/电力事件
try:
event_time = dt.datetime.strptime(
row.report_month, "%Y-%m"
).replace(tzinfo=dt.timezone.utc) if row.report_month else dt.datetime.now(dt.timezone.utc)
except ValueError:
event_time = dt.datetime.now(dt.timezone.utc)
event = MetricEvent(
event_time=event_time,
subject_type="contract",
subject_key=row.contract_no or row.cabinet_id,
metric_name="idc_cabinet",
metric_value=row.occupancy_rate or 0.0,
attributes={
"cabinet_id": row.cabinet_id,
"customer_key": row.customer_key,
"power_kwh": row.power_kwh,
"revenue_amount": row.revenue_amount,
"acceptance_date": str(row.acceptance_date) if row.acceptance_date else None,
},
data_version_id=data_version_id,
)
session.add(event)
result.metric_events.append(event)
result.row_count += 1
except Exception:
result.error_count += 1
return result