Bonus-Transfer-Machines/机具/ma_type.py

143 lines
5.4 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 pandas as pd
import sqlalchemy
from sqlalchemy import create_engine
import configparser
import os
from urllib.parse import quote_plus
from datetime import datetime
def fix_date(date_str):
try:
# 处理只有年月的情况(如"2018-07"
if isinstance(date_str, str) and len(date_str) == 7 and date_str[4] == '-':
return datetime.strptime(date_str + '-01', '%Y-%m-%d')
return date_str
except:
return None # 对于无法解析的日期返回NULL
def get_db_connection_string(config, section):
"""从配置文件中构建数据库连接字符串"""
return f"mysql+pymysql://{config[section]['user']}:{quote_plus(config[section]['password'])}@" \
f"{config[section]['host']}:{config[section]['port']}/{config[section]['database']}"
def transform_and_load_ma_type(config_file_path):
"""
从源数据库提取ma_type数据转换后加载到目标数据库ma_type
:param config_file_path: 配置文件路径
"""
# 读取配置文件
if not os.path.exists(config_file_path):
raise FileNotFoundError(f"配置文件不存在: {config_file_path}")
config = configparser.ConfigParser()
config.read(config_file_path)
try:
# 获取数据库连接
source_conn_str = get_db_connection_string(config, 'source_db')
target_conn_str = get_db_connection_string(config, 'target_db')
source_engine = create_engine(source_conn_str)
target_engine = create_engine(target_conn_str)
# 从源表读取数据过滤COMPANY_ID=1且IS_ACTIVE=1的记录
print("正在从源表ma_type读取数据...")
source_query = """
SELECT ID, \
PARENT_ID, \
NAME, \
LEVEL, \
UNIT, \
NUM, \
nullif(BUY_PRICE,0) as BUY_PRICE, \
nullif(LEASE_PRICE,0) as LEASE_PRICE, \
IS_COUNT, \
RATED_LOAD, \
TEST_LOAD, \
HOLDING_TIME, \
manage_type,
nullif(IS_TEST,0) as IS_TEST,
nullif(TIME,0) as TIME
FROM ma_type
WHERE COMPANY_ID = 1 AND IS_ACTIVE = 1 \
"""
source_df = pd.read_sql(source_query, source_engine)
if source_df.empty:
print("没有符合条件的数据需要转换")
return
print(f"读取到{len(source_df)}条待转换数据")
# 数据转换(直接字段复制)
print("正在进行数据转换...")
target_df = pd.DataFrame()
# 字段映射(源字段 → 目标字段)
field_mapping = {
'ID': 'type_id',
'PARENT_ID': 'parent_id',
'NAME': 'type_name',
'LEVEL': 'level',
'UNIT': 'unit_name',
'NUM': 'storage_num',
'BUY_PRICE': 'buy_price',
'LEASE_PRICE': 'lease_price',
'IS_COUNT': 'manage_type',
'RATED_LOAD': 'rated_load',
'TEST_LOAD': 'test_load',
'HOLDING_TIME': 'holding_time',
'manage_type': 'is_enter',
'IS_TEST': 'is_test',
'TIME': 'create_time'
}
for source_field, target_field in field_mapping.items():
target_df[target_field] = source_df[source_field]
# 应用日期修正
target_df['create_time'] = source_df['TIME'].apply(fix_date)
# 写入目标表
print("正在写入目标表ma_type...")
target_df.to_sql(
'ma_type',
target_engine,
if_exists='append',
index=False,
dtype={
'type_id': sqlalchemy.types.INTEGER(),
'parent_id': sqlalchemy.types.INTEGER(),
'type_name': sqlalchemy.types.VARCHAR(length=100),
'level': sqlalchemy.types.SmallInteger(),
'unit_name': sqlalchemy.types.VARCHAR(length=20),
'storage_num': sqlalchemy.types.VARCHAR(length=50),
'buy_price': sqlalchemy.types.DECIMAL(10, 2),
'lease_price': sqlalchemy.types.DECIMAL(10, 2),
'manage_type': sqlalchemy.types.SmallInteger(),
'rated_load': sqlalchemy.types.DECIMAL(10, 2),
'test_load': sqlalchemy.types.DECIMAL(10, 2),
'holding_time': sqlalchemy.types.INTEGER(),
'is_enter': sqlalchemy.types.SmallInteger(),
'is_test': sqlalchemy.types.SmallInteger(),
'create_time': sqlalchemy.types.DateTime()
}
)
print(f"成功写入{len(target_df)}条数据")
except Exception as e:
print(f"处理过程中发生错误: {str(e)}")
raise
finally:
if 'source_engine' in locals():
source_engine.dispose()
if 'target_engine' in locals():
target_engine.dispose()
if __name__ == "__main__":
# 配置文件路径(根据实际情况修改)
config_file = "config.ini"
try:
transform_and_load_ma_type(config_file)
except Exception as e:
print(f"程序执行失败: {str(e)}")