You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python将格式不匹配的Excel数据导入指定PostgreSQL表

Python实现Excel数据转PostgreSQL表(适配父子测试结构)

需求说明

现有PostgreSQL表结构如下:

CREATE TABLE public.test (
    "Test_Id" int4 NOT NULL,
    "Test_Name" text NOT NULL,
    "Test_Code" text NULL,
    "Test_Description" text NOT NULL,
    "Test_Parent_Id" numeric NOT NULL,
    "Level_Test_Id" numeric NULL,
    "Level_Test_Name" text null
    CONSTRAINT "Test_Id_pkey" PRIMARY KEY ("Test_Id")
);

需要将格式不匹配的Excel数据导入该表,其中Excel包含父测试(如TestA)和子测试(如TestA indicator name A1.1),且Level_Test_Name可选值为('Level 1', 'Level 2', 'Level 3', 'Level 4','Level 5')。

依赖准备

先安装所需Python库:

pip install pandas psycopg2-binary openpyxl

代码实现

import pandas as pd
import psycopg2
from psycopg2 import sql

# 1. 读取Excel数据(假设Excel文件名为test_data.xlsx,数据在Sheet1)
df = pd.read_excel('test_data.xlsx', sheet_name='Sheet1', engine='openpyxl')

# 2. 预处理数据:识别父子测试,填充对应字段
# 先提取父测试列表(假设父测试名称不含"indicator"关键词,可根据实际调整规则)
parent_tests = df[~df['Test_Name'].str.contains('indicator')]['Test_Name'].unique()

# 创建父测试ID映射(这里Test_Id从1开始自增,可根据实际调整)
parent_id_map = {name: idx+1 for idx, name in enumerate(parent_tests)}

# 初始化结果列表
db_data = []
current_test_id = 1

# 遍历每条数据
for _, row in df.iterrows():
    test_name = row['Test_Name']
    test_code = row.get('Test_Code', None)
    test_desc = row['Test_Description']  # 假设Excel有该列,若无则需补充默认值
    
    # 判断是父测试还是子测试
    if test_name in parent_id_map:
        # 父测试:Test_Parent_Id设为0(顶级父节点),Level设为Level 1
        test_parent_id = 0
        level_test_name = 'Level 1'
        level_test_id = 1
        db_data.append({
            'Test_Id': current_test_id,
            'Test_Name': test_name,
            'Test_Code': test_code,
            'Test_Description': test_desc,
            'Test_Parent_Id': test_parent_id,
            'Level_Test_Id': level_test_id,
            'Level_Test_Name': level_test_name
        })
        parent_id_map[test_name] = current_test_id
        current_test_id += 1
    else:
        # 子测试:匹配对应的父测试(假设子测试名称以父测试名称开头)
        parent_name = next((name for name in parent_id_map if test_name.startswith(name)), None)
        if parent_name:
            test_parent_id = parent_id_map[parent_name]
            # 根据父级Level推导子级Level(这里假设父是Level1则子是Level2,可按需调整)
            level_test_id = 2
            level_test_name = 'Level 2'
            # 若有更深层级,可扩展判断逻辑
            # ...
        else:
            # 无匹配父测试的情况,可设为默认值或抛出异常
            test_parent_id = 0
            level_test_id = None
            level_test_name = None
        
        db_data.append({
            'Test_Id': current_test_id,
            'Test_Name': test_name,
            'Test_Code': test_code,
            'Test_Description': test_desc,
            'Test_Parent_Id': test_parent_id,
            'Level_Test_Id': level_test_id,
            'Level_Test_Name': level_test_name
        })
        current_test_id += 1

# 3. 连接PostgreSQL并写入数据
conn = psycopg2.connect(
    dbname='your_db_name',
    user='your_username',
    password='your_password',
    host='your_host',
    port='your_port'
)
cur = conn.cursor()

# 批量插入数据
insert_query = sql.SQL("""
    INSERT INTO public.test (
        "Test_Id", "Test_Name", "Test_Code", "Test_Description",
        "Test_Parent_Id", "Level_Test_Id", "Level_Test_Name"
    ) VALUES (%s, %s, %s, %s, %s, %s, %s)
""")

for item in db_data:
    cur.execute(insert_query, (
        item['Test_Id'],
        item['Test_Name'],
        item['Test_Code'],
        item['Test_Description'],
        item['Test_Parent_Id'],
        item['Level_Test_Id'],
        item['Level_Test_Name']
    ))

# 提交事务并关闭连接
conn.commit()
cur.close()
conn.close()

print("数据导入完成")

关键逻辑说明

  • 父子测试识别:通过判断Test_Name是否包含"indicator"关键词区分父/子测试,可根据Excel实际格式调整识别规则(比如前缀匹配、层级标识等)
  • Test_Id生成:采用自增方式生成,若Excel已有Test_Id列,可直接使用该列值
  • Level字段填充:示例中默认父测试为Level1,子测试为Level2,若有更深层级,可扩展逻辑(比如通过子测试名称中的编号如A1.1判断层级)
  • 异常处理:示例中对无匹配父测试的情况做了默认值处理,实际使用中可根据需求添加异常捕获或日志记录

内容的提问来源于stack exchange,提问作者Safa edligo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 13:43:12