2025-12-11 14:32:31 +08:00
|
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
"""
|
|
|
|
|
|
SQL Server 数据写入模块
|
|
|
|
|
|
将脚本返回的数据写入到 SQL Server 数据库
|
|
|
|
|
|
"""
|
|
|
|
|
|
import pyodbc
|
|
|
|
|
|
from typing import Dict, Any, Optional
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
from logger import get_logger
|
|
|
|
|
|
|
|
|
|
|
|
logger = get_logger()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SQLServerWriter:
|
|
|
|
|
|
"""SQL Server 数据写入器"""
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, connection_config: Dict[str, Any]):
|
|
|
|
|
|
"""
|
|
|
|
|
|
初始化 SQL Server 连接
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
connection_config: 连接配置
|
|
|
|
|
|
- host: 服务器地址
|
|
|
|
|
|
- port: 端口号(默认 1433)
|
|
|
|
|
|
- database: 数据库名
|
|
|
|
|
|
- username: 用户名
|
|
|
|
|
|
- password: 密码
|
|
|
|
|
|
"""
|
|
|
|
|
|
self.config = connection_config
|
|
|
|
|
|
self.connection = None
|
|
|
|
|
|
|
|
|
|
|
|
def connect(self) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
建立数据库连接
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
连接是否成功
|
|
|
|
|
|
"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
host = self.config.get('host', 'localhost')
|
|
|
|
|
|
port = self.config.get('port', 1433)
|
|
|
|
|
|
database = self.config.get('database', '')
|
|
|
|
|
|
username = self.config.get('username', '')
|
|
|
|
|
|
password = self.config.get('password', '')
|
|
|
|
|
|
|
|
|
|
|
|
if not database:
|
|
|
|
|
|
logger.error("SQL Server 数据库名未配置")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
# 尝试多个驱动
|
|
|
|
|
|
driver_candidates = [
|
|
|
|
|
|
"ODBC Driver 18 for SQL Server",
|
|
|
|
|
|
"ODBC Driver 17 for SQL Server",
|
|
|
|
|
|
"ODBC Driver 13 for SQL Server",
|
|
|
|
|
|
"SQL Server",
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
last_error = None
|
|
|
|
|
|
for driver in driver_candidates:
|
|
|
|
|
|
conn_str = (
|
|
|
|
|
|
f"DRIVER={{{driver}}};"
|
|
|
|
|
|
f"SERVER={host},{port};"
|
|
|
|
|
|
f"DATABASE={database};"
|
|
|
|
|
|
f"UID={username};"
|
|
|
|
|
|
f"PWD={password};"
|
|
|
|
|
|
f"TrustServerCertificate=yes"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.connection = pyodbc.connect(conn_str, timeout=10)
|
|
|
|
|
|
logger.info(f"SQL Server 连接成功 (驱动: {driver})")
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
last_error = e
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
logger.error(f"SQL Server 连接失败: {last_error}")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"SQL Server 连接异常: {e}", exc_info=True)
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def disconnect(self):
|
|
|
|
|
|
"""关闭数据库连接"""
|
|
|
|
|
|
if self.connection:
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.connection.close()
|
|
|
|
|
|
logger.info("SQL Server 连接已关闭")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"关闭 SQL Server 连接失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
def write_pump_600_data(self, data: Dict[str, Any]) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
写入 600 泵跑合数据
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
data: 脚本返回的数据字典,包含:
|
|
|
|
|
|
- order_no: 工单号(必填)
|
|
|
|
|
|
- runin_date: 跑合日期
|
|
|
|
|
|
- operator_name: 操作员
|
|
|
|
|
|
- power_end_part_no: 动力端零件号
|
|
|
|
|
|
- motor_speed_rpm: 电机转速
|
|
|
|
|
|
- ambient_temp_c: 环境温度
|
|
|
|
|
|
- start_time: 开始时间
|
|
|
|
|
|
- end_time: 结束时间
|
|
|
|
|
|
- reviewer_name: 审核人
|
|
|
|
|
|
- is_normal: 是否正常(1=正常,0=异常)
|
|
|
|
|
|
- abnormal_desc: 异常描述
|
|
|
|
|
|
- remarks: 备注
|
|
|
|
|
|
- temp_main_1_t05 ~ temp_main_1_t35: 主轴承1温度数据
|
|
|
|
|
|
- temp_main_2_t05 ~ temp_main_2_t35: 主轴承2温度数据
|
|
|
|
|
|
- temp_main_3_t05 ~ temp_main_3_t35: 主轴承3温度数据
|
|
|
|
|
|
- temp_main_4_t05 ~ temp_main_4_t35: 主轴承4温度数据
|
|
|
|
|
|
- temp_crosshead_1_t05 ~ temp_crosshead_1_t35: 十字头1温度数据
|
|
|
|
|
|
- temp_crosshead_2_t05 ~ temp_crosshead_2_t35: 十字头2温度数据
|
|
|
|
|
|
- temp_crosshead_3_t05 ~ temp_crosshead_3_t35: 十字头3温度数据
|
|
|
|
|
|
- temp_gbox_small_1_t05 ~ temp_gbox_small_1_t35: 小齿轮箱1温度数据
|
|
|
|
|
|
- temp_gbox_small_2_t05 ~ temp_gbox_small_2_t35: 小齿轮箱2温度数据
|
|
|
|
|
|
- temp_gbox_big_3_t05 ~ temp_gbox_big_3_t35: 大齿轮箱3温度数据
|
|
|
|
|
|
- temp_gbox_big_4_t05 ~ temp_gbox_big_4_t35: 大齿轮箱4温度数据
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
写入是否成功
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.connection:
|
|
|
|
|
|
logger.error("SQL Server 未连接")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 验证必填字段
|
|
|
|
|
|
order_no = data.get('order_no')
|
|
|
|
|
|
if not order_no:
|
|
|
|
|
|
logger.error("工单号(order_no)为必填字段")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
start_time = data.get('start_time')
|
|
|
|
|
|
end_time = data.get('end_time')
|
|
|
|
|
|
|
|
|
|
|
|
# 检查记录是否已存在(基于 order_no, start_time, end_time 组合)
|
|
|
|
|
|
cursor = self.connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
# 构建查询条件
|
|
|
|
|
|
if start_time and end_time:
|
|
|
|
|
|
# 如果有开始和结束时间,使用三个字段组合查询
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"""SELECT id FROM pump_600_no_load_run_in
|
|
|
|
|
|
WHERE order_no = ? AND start_time = ? AND end_time = ?""",
|
|
|
|
|
|
(order_no, start_time, end_time)
|
|
|
|
|
|
)
|
|
|
|
|
|
elif start_time:
|
|
|
|
|
|
# 只有开始时间
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"""SELECT id FROM pump_600_no_load_run_in
|
|
|
|
|
|
WHERE order_no = ? AND start_time = ?""",
|
|
|
|
|
|
(order_no, start_time)
|
|
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 只有工单号(向后兼容)
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"SELECT id FROM pump_600_no_load_run_in WHERE order_no = ?",
|
|
|
|
|
|
(order_no,)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
existing = cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
|
|
if existing:
|
|
|
|
|
|
existing_id = existing[0]
|
|
|
|
|
|
logger.info(
|
|
|
|
|
|
f"找到已存在的记录 (id={existing_id}, order_no={order_no}, "
|
|
|
|
|
|
f"start_time={start_time}, end_time={end_time}),将更新数据"
|
|
|
|
|
|
)
|
|
|
|
|
|
return self._update_pump_600_data_by_id(existing_id, data)
|
|
|
|
|
|
else:
|
|
|
|
|
|
logger.info(
|
|
|
|
|
|
f"未找到匹配记录 (order_no={order_no}, start_time={start_time}, "
|
|
|
|
|
|
f"end_time={end_time}),将插入新数据"
|
|
|
|
|
|
)
|
|
|
|
|
|
return self._insert_pump_600_data(data)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"写入 SQL Server 数据失败: {e}", exc_info=True)
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def _insert_pump_600_data(self, data: Dict[str, Any]) -> bool:
|
|
|
|
|
|
"""插入新记录"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
cursor = self.connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
# 构建 SQL 插入语句
|
|
|
|
|
|
sql = """
|
|
|
|
|
|
INSERT INTO pump_600_no_load_run_in (
|
|
|
|
|
|
order_no, runin_date, operator_name, power_end_part_no,
|
|
|
|
|
|
motor_speed_rpm, ambient_temp_c, start_time, end_time,
|
|
|
|
|
|
reviewer_name, is_normal, abnormal_desc, remarks,
|
|
|
|
|
|
temp_main_1_t05, temp_main_1_t10, temp_main_1_t15, temp_main_1_t20,
|
|
|
|
|
|
temp_main_1_t25, temp_main_1_t30, temp_main_1_t35,
|
|
|
|
|
|
temp_main_2_t05, temp_main_2_t10, temp_main_2_t15, temp_main_2_t20,
|
|
|
|
|
|
temp_main_2_t25, temp_main_2_t30, temp_main_2_t35,
|
|
|
|
|
|
temp_main_3_t05, temp_main_3_t10, temp_main_3_t15, temp_main_3_t20,
|
|
|
|
|
|
temp_main_3_t25, temp_main_3_t30, temp_main_3_t35,
|
|
|
|
|
|
temp_main_4_t05, temp_main_4_t10, temp_main_4_t15, temp_main_4_t20,
|
|
|
|
|
|
temp_main_4_t25, temp_main_4_t30, temp_main_4_t35,
|
|
|
|
|
|
temp_crosshead_1_t05, temp_crosshead_1_t10, temp_crosshead_1_t15, temp_crosshead_1_t20,
|
|
|
|
|
|
temp_crosshead_1_t25, temp_crosshead_1_t30, temp_crosshead_1_t35,
|
|
|
|
|
|
temp_crosshead_2_t05, temp_crosshead_2_t10, temp_crosshead_2_t15, temp_crosshead_2_t20,
|
|
|
|
|
|
temp_crosshead_2_t25, temp_crosshead_2_t30, temp_crosshead_2_t35,
|
|
|
|
|
|
temp_crosshead_3_t05, temp_crosshead_3_t10, temp_crosshead_3_t15, temp_crosshead_3_t20,
|
|
|
|
|
|
temp_crosshead_3_t25, temp_crosshead_3_t30, temp_crosshead_3_t35,
|
|
|
|
|
|
temp_gbox_small_1_t05, temp_gbox_small_1_t10, temp_gbox_small_1_t15, temp_gbox_small_1_t20,
|
|
|
|
|
|
temp_gbox_small_1_t25, temp_gbox_small_1_t30, temp_gbox_small_1_t35,
|
|
|
|
|
|
temp_gbox_small_2_t05, temp_gbox_small_2_t10, temp_gbox_small_2_t15, temp_gbox_small_2_t20,
|
|
|
|
|
|
temp_gbox_small_2_t25, temp_gbox_small_2_t30, temp_gbox_small_2_t35,
|
|
|
|
|
|
temp_gbox_big_3_t05, temp_gbox_big_3_t10, temp_gbox_big_3_t15, temp_gbox_big_3_t20,
|
|
|
|
|
|
temp_gbox_big_3_t25, temp_gbox_big_3_t30, temp_gbox_big_3_t35,
|
|
|
|
|
|
temp_gbox_big_4_t05, temp_gbox_big_4_t10, temp_gbox_big_4_t15, temp_gbox_big_4_t20,
|
|
|
|
|
|
temp_gbox_big_4_t25, temp_gbox_big_4_t30, temp_gbox_big_4_t35,
|
|
|
|
|
|
created_at, updated_at
|
|
|
|
|
|
) VALUES (
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?, ?, ?, ?, ?, ?,
|
|
|
|
|
|
?, ?
|
|
|
|
|
|
)
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
# 准备参数
|
|
|
|
|
|
now = datetime.now()
|
|
|
|
|
|
params = [
|
|
|
|
|
|
data.get('order_no'),
|
|
|
|
|
|
data.get('runin_date'),
|
|
|
|
|
|
data.get('operator_name'),
|
|
|
|
|
|
data.get('power_end_part_no'),
|
|
|
|
|
|
data.get('motor_speed_rpm'),
|
|
|
|
|
|
data.get('ambient_temp_c'),
|
|
|
|
|
|
data.get('start_time'),
|
|
|
|
|
|
data.get('end_time'),
|
|
|
|
|
|
data.get('reviewer_name'),
|
|
|
|
|
|
data.get('is_normal', 1), # 默认正常
|
|
|
|
|
|
data.get('abnormal_desc'),
|
|
|
|
|
|
data.get('remarks'),
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# 添加所有温度字段
|
|
|
|
|
|
temp_fields = [
|
|
|
|
|
|
'temp_main_1', 'temp_main_2', 'temp_main_3', 'temp_main_4',
|
|
|
|
|
|
'temp_crosshead_1', 'temp_crosshead_2', 'temp_crosshead_3',
|
|
|
|
|
|
'temp_gbox_small_1', 'temp_gbox_small_2',
|
|
|
|
|
|
'temp_gbox_big_3', 'temp_gbox_big_4'
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
time_points = ['t05', 't10', 't15', 't20', 't25', 't30', 't35']
|
|
|
|
|
|
|
|
|
|
|
|
for field in temp_fields:
|
|
|
|
|
|
for time_point in time_points:
|
|
|
|
|
|
key = f"{field}_{time_point}"
|
|
|
|
|
|
params.append(data.get(key))
|
|
|
|
|
|
|
|
|
|
|
|
# 添加时间戳
|
|
|
|
|
|
params.extend([now, now])
|
|
|
|
|
|
|
|
|
|
|
|
# 执行插入
|
|
|
|
|
|
cursor.execute(sql, params)
|
|
|
|
|
|
self.connection.commit()
|
|
|
|
|
|
|
|
|
|
|
|
logger.info(f"✅ 成功插入工单 {data.get('order_no')} 的数据到 SQL Server")
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"插入 SQL Server 数据失败: {e}", exc_info=True)
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.connection.rollback()
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def _update_pump_600_data_by_id(self, record_id: int, data: Dict[str, Any]) -> bool:
|
|
|
|
|
|
"""根据记录ID更新已存在的记录"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
cursor = self.connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
# 构建 SQL 更新语句
|
|
|
|
|
|
sql = """
|
|
|
|
|
|
UPDATE pump_600_no_load_run_in SET
|
|
|
|
|
|
order_no = ?, runin_date = ?, operator_name = ?, power_end_part_no = ?,
|
|
|
|
|
|
motor_speed_rpm = ?, ambient_temp_c = ?, start_time = ?, end_time = ?,
|
|
|
|
|
|
reviewer_name = ?, is_normal = ?, abnormal_desc = ?, remarks = ?,
|
|
|
|
|
|
temp_main_1_t05 = ?, temp_main_1_t10 = ?, temp_main_1_t15 = ?, temp_main_1_t20 = ?,
|
|
|
|
|
|
temp_main_1_t25 = ?, temp_main_1_t30 = ?, temp_main_1_t35 = ?,
|
|
|
|
|
|
temp_main_2_t05 = ?, temp_main_2_t10 = ?, temp_main_2_t15 = ?, temp_main_2_t20 = ?,
|
|
|
|
|
|
temp_main_2_t25 = ?, temp_main_2_t30 = ?, temp_main_2_t35 = ?,
|
|
|
|
|
|
temp_main_3_t05 = ?, temp_main_3_t10 = ?, temp_main_3_t15 = ?, temp_main_3_t20 = ?,
|
|
|
|
|
|
temp_main_3_t25 = ?, temp_main_3_t30 = ?, temp_main_3_t35 = ?,
|
|
|
|
|
|
temp_main_4_t05 = ?, temp_main_4_t10 = ?, temp_main_4_t15 = ?, temp_main_4_t20 = ?,
|
|
|
|
|
|
temp_main_4_t25 = ?, temp_main_4_t30 = ?, temp_main_4_t35 = ?,
|
|
|
|
|
|
temp_crosshead_1_t05 = ?, temp_crosshead_1_t10 = ?, temp_crosshead_1_t15 = ?, temp_crosshead_1_t20 = ?,
|
|
|
|
|
|
temp_crosshead_1_t25 = ?, temp_crosshead_1_t30 = ?, temp_crosshead_1_t35 = ?,
|
|
|
|
|
|
temp_crosshead_2_t05 = ?, temp_crosshead_2_t10 = ?, temp_crosshead_2_t15 = ?, temp_crosshead_2_t20 = ?,
|
|
|
|
|
|
temp_crosshead_2_t25 = ?, temp_crosshead_2_t30 = ?, temp_crosshead_2_t35 = ?,
|
|
|
|
|
|
temp_crosshead_3_t05 = ?, temp_crosshead_3_t10 = ?, temp_crosshead_3_t15 = ?, temp_crosshead_3_t20 = ?,
|
|
|
|
|
|
temp_crosshead_3_t25 = ?, temp_crosshead_3_t30 = ?, temp_crosshead_3_t35 = ?,
|
|
|
|
|
|
temp_gbox_small_1_t05 = ?, temp_gbox_small_1_t10 = ?, temp_gbox_small_1_t15 = ?, temp_gbox_small_1_t20 = ?,
|
|
|
|
|
|
temp_gbox_small_1_t25 = ?, temp_gbox_small_1_t30 = ?, temp_gbox_small_1_t35 = ?,
|
|
|
|
|
|
temp_gbox_small_2_t05 = ?, temp_gbox_small_2_t10 = ?, temp_gbox_small_2_t15 = ?, temp_gbox_small_2_t20 = ?,
|
|
|
|
|
|
temp_gbox_small_2_t25 = ?, temp_gbox_small_2_t30 = ?, temp_gbox_small_2_t35 = ?,
|
|
|
|
|
|
temp_gbox_big_3_t05 = ?, temp_gbox_big_3_t10 = ?, temp_gbox_big_3_t15 = ?, temp_gbox_big_3_t20 = ?,
|
|
|
|
|
|
temp_gbox_big_3_t25 = ?, temp_gbox_big_3_t30 = ?, temp_gbox_big_3_t35 = ?,
|
|
|
|
|
|
temp_gbox_big_4_t05 = ?, temp_gbox_big_4_t10 = ?, temp_gbox_big_4_t15 = ?, temp_gbox_big_4_t20 = ?,
|
|
|
|
|
|
temp_gbox_big_4_t25 = ?, temp_gbox_big_4_t30 = ?, temp_gbox_big_4_t35 = ?,
|
|
|
|
|
|
updated_at = ?
|
|
|
|
|
|
WHERE id = ?
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
# 准备参数
|
|
|
|
|
|
now = datetime.now()
|
|
|
|
|
|
params = [
|
|
|
|
|
|
data.get('order_no'),
|
|
|
|
|
|
data.get('runin_date'),
|
|
|
|
|
|
data.get('operator_name'),
|
|
|
|
|
|
data.get('power_end_part_no'),
|
|
|
|
|
|
data.get('motor_speed_rpm'),
|
|
|
|
|
|
data.get('ambient_temp_c'),
|
|
|
|
|
|
data.get('start_time'),
|
|
|
|
|
|
data.get('end_time'),
|
|
|
|
|
|
data.get('reviewer_name'),
|
|
|
|
|
|
data.get('is_normal', 1),
|
|
|
|
|
|
data.get('abnormal_desc'),
|
|
|
|
|
|
data.get('remarks'),
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# 添加所有温度字段
|
|
|
|
|
|
temp_fields = [
|
|
|
|
|
|
'temp_main_1', 'temp_main_2', 'temp_main_3', 'temp_main_4',
|
|
|
|
|
|
'temp_crosshead_1', 'temp_crosshead_2', 'temp_crosshead_3',
|
|
|
|
|
|
'temp_gbox_small_1', 'temp_gbox_small_2',
|
|
|
|
|
|
'temp_gbox_big_3', 'temp_gbox_big_4'
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
time_points = ['t05', 't10', 't15', 't20', 't25', 't30', 't35']
|
|
|
|
|
|
|
|
|
|
|
|
for field in temp_fields:
|
|
|
|
|
|
for time_point in time_points:
|
|
|
|
|
|
key = f"{field}_{time_point}"
|
|
|
|
|
|
params.append(data.get(key))
|
|
|
|
|
|
|
|
|
|
|
|
# 添加更新时间和记录ID
|
|
|
|
|
|
params.extend([now, record_id])
|
|
|
|
|
|
|
|
|
|
|
|
# 执行更新
|
|
|
|
|
|
cursor.execute(sql, params)
|
|
|
|
|
|
self.connection.commit()
|
|
|
|
|
|
|
|
|
|
|
|
logger.info(f"✅ 成功更新记录 (id={record_id}, order_no={data.get('order_no')}) 到 SQL Server")
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"更新 SQL Server 数据失败: {e}", exc_info=True)
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.connection.rollback()
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def _update_pump_600_data(self, order_no: str, data: Dict[str, Any]) -> bool:
|
|
|
|
|
|
"""更新已存在的记录(向后兼容,已废弃)"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
cursor = self.connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
# 构建 SQL 更新语句
|
|
|
|
|
|
sql = """
|
|
|
|
|
|
UPDATE pump_600_no_load_run_in SET
|
|
|
|
|
|
runin_date = ?, operator_name = ?, power_end_part_no = ?,
|
|
|
|
|
|
motor_speed_rpm = ?, ambient_temp_c = ?, start_time = ?, end_time = ?,
|
|
|
|
|
|
reviewer_name = ?, is_normal = ?, abnormal_desc = ?, remarks = ?,
|
|
|
|
|
|
temp_main_1_t05 = ?, temp_main_1_t10 = ?, temp_main_1_t15 = ?, temp_main_1_t20 = ?,
|
|
|
|
|
|
temp_main_1_t25 = ?, temp_main_1_t30 = ?, temp_main_1_t35 = ?,
|
|
|
|
|
|
temp_main_2_t05 = ?, temp_main_2_t10 = ?, temp_main_2_t15 = ?, temp_main_2_t20 = ?,
|
|
|
|
|
|
temp_main_2_t25 = ?, temp_main_2_t30 = ?, temp_main_2_t35 = ?,
|
|
|
|
|
|
temp_main_3_t05 = ?, temp_main_3_t10 = ?, temp_main_3_t15 = ?, temp_main_3_t20 = ?,
|
|
|
|
|
|
temp_main_3_t25 = ?, temp_main_3_t30 = ?, temp_main_3_t35 = ?,
|
|
|
|
|
|
temp_main_4_t05 = ?, temp_main_4_t10 = ?, temp_main_4_t15 = ?, temp_main_4_t20 = ?,
|
|
|
|
|
|
temp_main_4_t25 = ?, temp_main_4_t30 = ?, temp_main_4_t35 = ?,
|
|
|
|
|
|
temp_crosshead_1_t05 = ?, temp_crosshead_1_t10 = ?, temp_crosshead_1_t15 = ?, temp_crosshead_1_t20 = ?,
|
|
|
|
|
|
temp_crosshead_1_t25 = ?, temp_crosshead_1_t30 = ?, temp_crosshead_1_t35 = ?,
|
|
|
|
|
|
temp_crosshead_2_t05 = ?, temp_crosshead_2_t10 = ?, temp_crosshead_2_t15 = ?, temp_crosshead_2_t20 = ?,
|
|
|
|
|
|
temp_crosshead_2_t25 = ?, temp_crosshead_2_t30 = ?, temp_crosshead_2_t35 = ?,
|
|
|
|
|
|
temp_crosshead_3_t05 = ?, temp_crosshead_3_t10 = ?, temp_crosshead_3_t15 = ?, temp_crosshead_3_t20 = ?,
|
|
|
|
|
|
temp_crosshead_3_t25 = ?, temp_crosshead_3_t30 = ?, temp_crosshead_3_t35 = ?,
|
|
|
|
|
|
temp_gbox_small_1_t05 = ?, temp_gbox_small_1_t10 = ?, temp_gbox_small_1_t15 = ?, temp_gbox_small_1_t20 = ?,
|
|
|
|
|
|
temp_gbox_small_1_t25 = ?, temp_gbox_small_1_t30 = ?, temp_gbox_small_1_t35 = ?,
|
|
|
|
|
|
temp_gbox_small_2_t05 = ?, temp_gbox_small_2_t10 = ?, temp_gbox_small_2_t15 = ?, temp_gbox_small_2_t20 = ?,
|
|
|
|
|
|
temp_gbox_small_2_t25 = ?, temp_gbox_small_2_t30 = ?, temp_gbox_small_2_t35 = ?,
|
|
|
|
|
|
temp_gbox_big_3_t05 = ?, temp_gbox_big_3_t10 = ?, temp_gbox_big_3_t15 = ?, temp_gbox_big_3_t20 = ?,
|
|
|
|
|
|
temp_gbox_big_3_t25 = ?, temp_gbox_big_3_t30 = ?, temp_gbox_big_3_t35 = ?,
|
|
|
|
|
|
temp_gbox_big_4_t05 = ?, temp_gbox_big_4_t10 = ?, temp_gbox_big_4_t15 = ?, temp_gbox_big_4_t20 = ?,
|
|
|
|
|
|
temp_gbox_big_4_t25 = ?, temp_gbox_big_4_t30 = ?, temp_gbox_big_4_t35 = ?,
|
|
|
|
|
|
updated_at = ?
|
|
|
|
|
|
WHERE order_no = ?
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
# 准备参数
|
|
|
|
|
|
now = datetime.now()
|
|
|
|
|
|
params = [
|
|
|
|
|
|
data.get('runin_date'),
|
|
|
|
|
|
data.get('operator_name'),
|
|
|
|
|
|
data.get('power_end_part_no'),
|
|
|
|
|
|
data.get('motor_speed_rpm'),
|
|
|
|
|
|
data.get('ambient_temp_c'),
|
|
|
|
|
|
data.get('start_time'),
|
|
|
|
|
|
data.get('end_time'),
|
|
|
|
|
|
data.get('reviewer_name'),
|
|
|
|
|
|
data.get('is_normal', 1),
|
|
|
|
|
|
data.get('abnormal_desc'),
|
|
|
|
|
|
data.get('remarks'),
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# 添加所有温度字段
|
|
|
|
|
|
temp_fields = [
|
|
|
|
|
|
'temp_main_1', 'temp_main_2', 'temp_main_3', 'temp_main_4',
|
|
|
|
|
|
'temp_crosshead_1', 'temp_crosshead_2', 'temp_crosshead_3',
|
|
|
|
|
|
'temp_gbox_small_1', 'temp_gbox_small_2',
|
|
|
|
|
|
'temp_gbox_big_3', 'temp_gbox_big_4'
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
time_points = ['t05', 't10', 't15', 't20', 't25', 't30', 't35']
|
|
|
|
|
|
|
|
|
|
|
|
for field in temp_fields:
|
|
|
|
|
|
for time_point in time_points:
|
|
|
|
|
|
key = f"{field}_{time_point}"
|
|
|
|
|
|
params.append(data.get(key))
|
|
|
|
|
|
|
|
|
|
|
|
# 添加更新时间和工单号
|
|
|
|
|
|
params.extend([now, order_no])
|
|
|
|
|
|
|
|
|
|
|
|
# 执行更新
|
|
|
|
|
|
cursor.execute(sql, params)
|
|
|
|
|
|
self.connection.commit()
|
|
|
|
|
|
|
|
|
|
|
|
logger.info(f"✅ 成功更新工单 {order_no} 的数据到 SQL Server")
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"更新 SQL Server 数据失败: {e}", exc_info=True)
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.connection.rollback()
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_script_data_to_sqlserver(script_data: Dict[str, Any], sqlserver_config: Dict[str, Any]) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
将脚本数据写入 SQL Server
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
script_data: 脚本返回的数据
|
|
|
|
|
|
sqlserver_config: SQL Server 连接配置
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
写入是否成功
|
|
|
|
|
|
"""
|
|
|
|
|
|
writer = SQLServerWriter(sqlserver_config)
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 连接数据库
|
|
|
|
|
|
if not writer.connect():
|
|
|
|
|
|
logger.error("无法连接到 SQL Server")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
# 写入数据
|
|
|
|
|
|
success = writer.write_pump_600_data(script_data)
|
|
|
|
|
|
|
|
|
|
|
|
return success
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"写入 SQL Server 失败: {e}", exc_info=True)
|
|
|
|
|
|
return False
|
|
|
|
|
|
finally:
|
|
|
|
|
|
writer.disconnect()
|
2026-01-16 14:47:53 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def verify_data_in_sqlserver(order_no: str, start_time: str, end_time: str, sqlserver_config: Dict[str, Any]) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
验证数据是否已写入 SQL Server
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
order_no: 工单号
|
|
|
|
|
|
start_time: 开始时间
|
|
|
|
|
|
end_time: 结束时间
|
|
|
|
|
|
sqlserver_config: SQL Server 连接配置
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
数据是否存在
|
|
|
|
|
|
"""
|
|
|
|
|
|
writer = SQLServerWriter(sqlserver_config)
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 连接数据库
|
|
|
|
|
|
if not writer.connect():
|
|
|
|
|
|
logger.error("无法连接到 SQL Server 进行验证")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
cursor = writer.connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
# 查询数据是否存在
|
|
|
|
|
|
if start_time and end_time:
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"""SELECT COUNT(*) FROM pump_600_no_load_run_in
|
|
|
|
|
|
WHERE order_no = ? AND start_time = ? AND end_time = ?""",
|
|
|
|
|
|
(order_no, start_time, end_time)
|
|
|
|
|
|
)
|
|
|
|
|
|
elif start_time:
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"""SELECT COUNT(*) FROM pump_600_no_load_run_in
|
|
|
|
|
|
WHERE order_no = ? AND start_time = ?""",
|
|
|
|
|
|
(order_no, start_time)
|
|
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"SELECT COUNT(*) FROM pump_600_no_load_run_in WHERE order_no = ?",
|
|
|
|
|
|
(order_no,)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
count = cursor.fetchone()[0]
|
|
|
|
|
|
exists = count > 0
|
|
|
|
|
|
|
|
|
|
|
|
if exists:
|
|
|
|
|
|
logger.info(f"✅ 验证成功:数据已存在于 SQL Server (order_no={order_no})")
|
|
|
|
|
|
else:
|
|
|
|
|
|
logger.warning(f"⚠ 验证失败:数据不存在于 SQL Server (order_no={order_no})")
|
|
|
|
|
|
|
|
|
|
|
|
return exists
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"验证 SQL Server 数据失败: {e}", exc_info=True)
|
|
|
|
|
|
return False
|
|
|
|
|
|
finally:
|
|
|
|
|
|
writer.disconnect()
|