Jonvy

导航

恢复条码至compvalue里

1.来源于问题:如果要向数据库里插入3000多条记录,可以写一个SQL语句,将这3000多条记录写在语句内一次性插入,也可以做个程序用循环的方法,每次插入一条记录,循环3000次,这2种方法对于数据库来讲,一样吗,哪种更高效?

答:

简而言之:这两种方法对数据库来说是不一样的**,而且一次性插入所有记录的SQL语句(批量插入)通常比循环插入单条记录高效得多

 

🚀 两种插入方式的效率对比

 

特性 批量插入(一条语句,多条记录) 循环插入(3000次,每次一条记录)
SQL 语句示例 INSERT INTO table (col1, col2) VALUES (1, 'a'), (2, 'b'), ..., (3000, 'z'); 循环内:INSERT INTO table (col1, col2) VALUES (i, 'value_i');
数据库交互次数 1次(数据库只需要处理一个请求) 3000次(需要处理3000个独立请求)
事务开销 (通常在一个事务内完成) (如果每次循环都是一个独立事务,开销巨大)
网络开销 (一次网络传输大量数据) (3000次往返的网络传输)
解析/优化开销 (SQL解析器和优化器只工作一次) (需要解析和优化3000次相同的语句结构)
效率 极高推荐 极低应避免

 

对于 PostgreSQL,最佳方案:使用 COPY 命令

 

2.使用python将input.csv中的et_refcmp,stocpf_no_cli,et_qualpf,stocpf_finish_date,nommodif,datemodif,heuremodif字段转换为output.csv文件中的et_refcmp,compvalue_nocomp,compvalue_value,compvalue_deb_validite,nommodif,datemodif,heuremodif字段,同时output.csv文件中增加一个et_carcli整数类型的字段,et_carcli的值为固定的值-4,et_carcli在output.csv文件中为第一个字段

输入input.csv文件为从服务器stocpf表格中客户条码查到的数据(该数据首先由t_compvalue lazarus程序转换格式,然后在SQL server中查询,查询语句见文章

SQL Server批量查询外部数据 

 
 

)

import csv
from typing import Dict, List, Any


def general_csv_converter(
        input_filename: str,
        output_filename: str,
        field_mapping: Dict[str, str],
        new_fixed_field: str,
        fixed_value: Any,
        insert_position: int = 0
):
    """
    读取 CSV 文件,根据提供的映射规则转换字段,并插入一个固定值的新字段。

    :param input_filename: 输入 CSV 文件的路径。
    :param output_filename: 输出 CSV 文件的路径。
    :param field_mapping: 旧字段名 (key) 到新字段名 (value) 的映射字典。
    :param new_fixed_field: 要新增的固定值字段的名称。
    :param fixed_value: 新增字段的固定值。
    :param insert_position: 新增字段在输出文件中的索引位置(默认0,即第一列)。
    """

    print(f"--- 开始处理文件:{input_filename} ---")

    # 根据映射关系推导出所需的输入字段和输出字段
    REQUIRED_INPUT_FIELDS = list(field_mapping.keys())
    # 基础输出字段是映射后的新字段名
    BASE_OUTPUT_FIELDS = list(field_mapping.values())

    # 构建最终的输出字段列表,并将固定值字段插入到指定位置
    OUTPUT_FIELDS = BASE_OUTPUT_FIELDS
    OUTPUT_FIELDS.insert(insert_position, new_fixed_field)

    try:
        with open(input_filename, mode='r', encoding='utf-8', newline='') as infile, \
                open(output_filename, mode='w', encoding='utf-8', newline='') as outfile:

            reader = csv.DictReader(infile)

            # 1. 检查输入文件是否包含所有必需的字段
            missing_fields = [f for f in REQUIRED_INPUT_FIELDS if f not in reader.fieldnames]
            if missing_fields:
                raise ValueError(f"输入文件缺少必需的字段: {missing_fields}")

            writer = csv.DictWriter(outfile, fieldnames=OUTPUT_FIELDS)
            writer.writeheader()

            row_count = 0

            for input_row in reader:
                output_row = {}

                # A. 插入新增的固定字段及其值
                output_row[new_fixed_field] = fixed_value

                # B. 根据映射关系转换其他字段
                for old_field, new_field in field_mapping.items():
                    output_row[new_field] = input_row[old_field]

                writer.writerow(output_row)
                row_count += 1

            print(f"成功转换并写入 {row_count} 条记录到 {output_filename}")

    except FileNotFoundError:
        print(f"错误:找不到文件 {input_filename}")
    except ValueError as e:
        print(f"数据错误: {e}")
    except Exception as e:
        print(f"处理过程中发生未知错误: {e}")


# --- 应用程序示例:使用通用函数执行您的特定任务 ---

if __name__ == "__main__":
    # 您的特定需求参数
    INPUT_FILE = "input.csv"
    OUTPUT_FILE = "output.csv"

    # 1. 定义字段映射关系 (旧字段名: 新字段名)
    YOUR_FIELD_MAPPING = {
        "ET_REFCMP": "ET_REFCMP",
        "STOCPF_NO_CLI": "COMPVALUE_NOCOMP",
        "ET_QUALPF": "COMPVALUE_VALUE",
        "STOCPF_FINISH_DATE": "COMPVALUE_DEB_VALIDITE",
        "NOMMODIF": "NOMMODIF",
        "DATEMODIF": "DATEMODIF",
        "HEUREMODIF": "HEUREMODIF",
    }

    # 2. 定义新增字段及其固定值
    NEW_FIELD_NAME = "et_carcli"
    FIXED_VALUE = -4  # 整数类型

    # 3. 定义新增字段的插入位置 (0 表示第一列)
    INSERT_POS = 0

    general_csv_converter(
        input_filename=INPUT_FILE,
        output_filename=OUTPUT_FILE,
        field_mapping=YOUR_FIELD_MAPPING,
        new_fixed_field=NEW_FIELD_NAME,
        fixed_value=FIXED_VALUE,
        insert_position=INSERT_POS
    )

  在pgAdmin中:输入以下指令

COPY t_compvalue (et_carcli,ET_REFCMP,COMPVALUE_NOCOMP,COMPVALUE_VALUE,COMPVALUE_DEB_VALIDITE,NOMMODIF,DATEMODIF,HEUREMODIF)
FROM 'C:/Temp/csvConvert/output.csv' 
WITH (FORMAT CSV, HEADER);

  注意: 这里的路径及文件 :

C:/Temp/csvConvert/output.csv是目标电脑上的目录和文件,而不是客户端本身的路径。

posted on 2025-12-13 22:11  不亮  阅读(1)  评论(0)    收藏  举报