Bonus-Transfer-Machines/安全/1.py

290 lines
10 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.

import configparser
import pandas as pd
import sqlalchemy
from sqlalchemy import create_engine
from urllib.parse import quote_plus
# 读取配置文件
config = configparser.ConfigParser()
config.read('config.ini')
# 获取数据库连接配置
source_config = {
'host': config.get('source_db', 'host'),
'user': config.get('source_db', 'user'),
'password': config.get('source_db', 'password'),
'database': config.get('source_db', 'database'),
'port': config.getint('source_db', 'port')
}
target_config = {
'host': config.get('target_db', 'host'),
'user': config.get('target_db', 'user'),
'password': config.get('target_db', 'password'),
'database': config.get('target_db', 'database'),
'port': config.getint('target_db', 'port')
}
def analyze_sql_and_output():
# 2. 建立数据库连接
# 创建数据库引擎
source_engine = create_engine(
f"mysql+pymysql://{source_config['user']}:{quote_plus(source_config['password'])}@{source_config['host']}:{source_config['port']}/{source_config['database']}"
)
target_engine = create_engine(
f"mysql+pymysql://{target_config['user']}:{quote_plus(target_config['password'])}@{target_config['host']}:{target_config['port']}/{target_config['database']}"
)
# 3. 定义SQL查询语句
collar_sql = """
SELECT
bat.AGREEMENT_ID AS agreement_id,
bmc.ID as lease_id,
mm.TYPE as type_id,
mm.ID as ma_id,
ttm.CREATE_TIME as start_time,
1 as num,
IF(bma.IS_BALANCE = 0,1,0) as is_slt,
bma.SETTLEMENT_TIME as slt_time,
mt.IS_COUNT,
mt.lease_price
FROM
ba_ma_collar bmc
LEFT JOIN ba_agreement_task bat on bmc.ID = bat.TASK_ID
LEFT JOIN ba_ma_agreement bma on bat.AGREEMENT_ID = bma.ID
LEFT JOIN tm_task_ma ttm on bmc.ID = ttm.TASK_ID
LEFT JOIN ma_machines mm on ttm.MA_ID = mm.ID
LEFT JOIN ma_type mt on mm.TYPE = mt.ID
WHERE bmc.company_id =1 AND mt.IS_COUNT = 0
UNION
SELECT
bat.AGREEMENT_ID AS agreement_id,
bmc.ID as lease_id,
ttot.MA_TYPE_ID as type_id,
null as ma_id,
ttot.CREATE_TIME as start_time,
ttot.NUM as num,
IF(bma.IS_BALANCE = 0,1,0) as is_slt,
bma.SETTLEMENT_TIME as slt_time,
mt.IS_COUNT,
mt.lease_price
FROM
ba_ma_collar bmc
LEFT JOIN ba_agreement_task bat on bmc.ID = bat.TASK_ID
LEFT JOIN ba_ma_agreement bma on bat.AGREEMENT_ID = bma.ID
LEFT JOIN tm_task_out_type ttot on bmc.ID = ttot.TASK_ID
LEFT JOIN ma_type mt on ttot.MA_TYPE_ID = mt.ID
WHERE bmc.company_id =1 AND ttot.IS_COUNT =1;
"""
back_sql = """
SELECT
bat.AGREEMENT_ID AS agreement_id,
bmb.ID as back_id,
mm.TYPE as type_id,
mm.ID as ma_id,
ttm.CREATE_TIME as end_time,
1 as num,
mt.IS_COUNT
FROM
ba_ma_back bmb
LEFT JOIN ba_agreement_task bat on bmb.ID = bat.TASK_ID
LEFT JOIN ba_ma_agreement bma on bat.AGREEMENT_ID = bma.ID
LEFT JOIN tm_task_ma ttm on bmb.ID = ttm.TASK_ID
LEFT JOIN ma_machines mm on ttm.MA_ID = mm.ID
LEFT JOIN ma_type mt on mm.TYPE = mt.ID
WHERE mt.IS_COUNT = 0
UNION
SELECT
bat.AGREEMENT_ID AS agreement_id,
bmb.id as back_id,
ttmt.MA_TYPE_ID as type_id,
null as maId,
bmb.CREATE_TIME as end_time,
ROUND(ttmt.MACHINES_NUM,3) as num,
ttmt.IS_COUNT
FROM
ba_ma_back bmb
LEFT JOIN ba_agreement_task bat on bmb.ID = bat.TASK_ID
LEFT JOIN ba_ma_agreement bma on bat.AGREEMENT_ID = bma.ID
LEFT JOIN tm_task_ma_type ttmt on bmb.ID = ttmt.TASK_ID
LEFT JOIN pm_user pu on bmb.CREATOR = pu.ID
WHERE ttmt.IS_COUNT =1
"""
price_sql = """
SELECT
ph.id,
ph.type_id,
ph.start_time,
ph.end_time,
ph.lease_price
FROM
lease_price_his ph
WHERE is_active =1
"""
# 4. 执行SQL查询获取原始数据
collar_df = pd.read_sql(collar_sql, source_engine)
back_df = pd.read_sql(back_sql, source_engine)
price_df = pd.read_sql(price_sql, source_engine)
# 5. 处理数据,按照规则进行匹配
result_list = []
# 处理IS_COUNT=0的情况
count0_collar = collar_df[collar_df['IS_COUNT'] == 0]
for _, row in count0_collar.iterrows():
# 在退料查询中查找相同的agreement_id和ma_id
matched_back = back_df[(back_df['agreement_id'] == row['agreement_id']) &
(back_df['ma_id'] == row['ma_id'])]
if not matched_back.empty:
end_time = matched_back.iloc[0]['end_time']
back_id = matched_back.iloc[0]['back_id']
status = '已退料'
else:
end_time = None
back_id = None
status = '未退料'
# 检查租赁单价区间
lease_price = row['lease_price']
price_match = price_df[(price_df['type_id'] == row['type_id']) &
(price_df['start_time'] <= row['start_time']) &
(price_df['end_time'] >= row['start_time'])]
if not price_match.empty:
lease_price = price_match.iloc[0]['lease_price']
# 构建结果行
result_row = {
'agreement_id': row['agreement_id'],
'type_id': row['type_id'],
'ma_id': row['ma_id'],
'num': row['num'],
'start_time': row['start_time'],
'end_time': end_time,
'status': status,
'lease_id': row['lease_id'],
'back_id': back_id,
'lease_price': lease_price,
'buy_price': None, # 根据实际情况补充
'is_slt': row['is_slt'],
'slt_time': row['slt_time']
}
result_list.append(result_row)
# 处理IS_COUNT=1的情况
count1_collar = collar_df[collar_df['IS_COUNT'] == 1]
for _, row in count1_collar.iterrows():
# 按时间顺序正序查找相同的agreement_id和type_id
matched_backs = back_df[(back_df['agreement_id'] == row['agreement_id']) &
(back_df['type_id'] == row['type_id'])].sort_values('end_time')
remaining_num = float(row['num'])
for _, back_row in matched_backs.iterrows():
if float(remaining_num) <= 0:
break
if back_row['num'] == remaining_num:
# 数量相等,直接匹配
result_row = {
'agreement_id': row['agreement_id'],
'type_id': row['type_id'],
'ma_id': row['ma_id'],
'num': remaining_num,
'start_time': row['start_time'],
'end_time': back_row['end_time'],
'status': '已退料',
'lease_id': row['lease_id'],
'back_id': back_row['back_id'],
'lease_price': row['lease_price'],
'buy_price': None,
'is_slt': row['is_slt'],
'slt_time': row['slt_time']
}
result_list.append(result_row)
remaining_num = 0.0
elif float(back_row['num']) < remaining_num:
# 退料数量小于领料数量,拆分
result_row1 = {
'agreement_id': row['agreement_id'],
'type_id': row['type_id'],
'ma_id': row['ma_id'],
'num': back_row['num'],
'start_time': row['start_time'],
'end_time': back_row['end_time'],
'status': '已退料',
'lease_id': row['lease_id'],
'back_id': back_row['back_id'],
'lease_price': row['lease_price'],
'buy_price': None,
'is_slt': row['is_slt'],
'slt_time': row['slt_time']
}
result_list.append(result_row1)
remaining_num -= float(back_row['num'])
else:
# 退料数量大于领料数量,匹配剩余部分
result_row = {
'agreement_id': row['agreement_id'],
'type_id': row['type_id'],
'ma_id': row['ma_id'],
'num': remaining_num,
'start_time': row['start_time'],
'end_time': back_row['end_time'],
'status': '已退料',
'lease_id': row['lease_id'],
'back_id': back_row['back_id'],
'lease_price': row['lease_price'],
'buy_price': None,
'is_slt': row['is_slt'],
'slt_time': row['slt_time']
}
result_list.append(result_row)
remaining_num = 0
# 处理未匹配完的领料
if float(remaining_num) > 0:
result_row = {
'agreement_id': row['agreement_id'],
'type_id': row['type_id'],
'ma_id': row['ma_id'],
'num': remaining_num,
'start_time': row['start_time'],
'end_time': None,
'status': '未退料',
'lease_id': row['lease_id'],
'back_id': None,
'lease_price': row['lease_price'],
'buy_price': None,
'is_slt': row['is_slt'],
'slt_time': row['slt_time']
}
result_list.append(result_row)
# 6. 创建结果DataFrame并输出到目标表
result_df = pd.DataFrame(result_list)
# 检查租赁单价区间并更新lease_price
for idx, row in result_df.iterrows():
if pd.isna(row['start_time']):
continue
price_match = price_df[(price_df['type_id'] == row['type_id']) &
(price_df['start_time'] <= row['start_time']) &
(price_df['end_time'] >= row['start_time'])]
if not price_match.empty:
result_df.at[idx, 'lease_price'] = price_match.iloc[0]['lease_price']
# 输出到目标表
result_df.to_sql('slt_agreement_info', target_engine, if_exists='replace', index=False)
print("数据处理完成已输出到slt_agreement_info表")
# 执行函数
analyze_sql_and_output()