<think>我们面对的需求是:在Python中,使用for循环将CSV文件分别插入到数据库的summary和daily两张表中,并在循环中增加一个“修数函数”,该函数的作用是执行一个SQL查询(从SPC_CHART_DAILYHL表中统计数量),并将结果更新到DAILY_CHART_SUMMARY表的对应字段中。注意,这个修数操作需要在for循环结束后进行,并且需要传递参数。
根据引用内容,我们可以利用以下技术:
1. 引用[1]和[3]展示了两种将数据插入数据库的方法:使用`executemany`和`to_sql`。但考虑到我们需要在插入后执行修数操作(即更新另一张表),并且有特定的参数传递要求,这里我们选择使用参数化查询。
2. 引用[2]和[4]展示了使用`LOAD DATA LOCAL INFILE`来快速导入CSV文件,但这种方法可能不适合我们同时插入两张表并后续执行修数操作,因为我们需要在Python中控制流程。
然而,用户要求使用for循环,这意味着我们可能需要对每一行数据或每个文件进行循环处理。这里假设我们要处理多个CSV文件,每个文件对应一次循环。
步骤分解:
1. 连接数据库(使用用户已有的连接方式,如引用[1]中的conn和cursor)。
2. 循环处理每个CSV文件(假设文件列表为csv_files):
a. 读取CSV文件到DataFrame(假设使用pandas)。
b. 将DataFrame数据插入到daily表(使用引用[1]的方法或引用[3]的to_sql方法,但注意表名不同)。
c. 同时,我们可能需要将部分数据插入到summary表?或者根据问题描述,summary表的修数是在循环结束后,且修数数据来源于daily表?所以这里我们先插入daily表,而summary表可能是另外的数据,或者也可能是从CSV中插入部分数据?问题描述中并没有明确summary表的数据来源,所以这里我们假设:
- daily表的数据直接来自CSV文件。
- summary表的数据需要从daily表聚合得到(通过修数函数),所以summary表可能不需要在循环中插入,而是在循环结束后更新。
但问题描述中要求“在for循环结束后进行summary表的修数操作”,并且修数操作是一个更新操作,将SPC_CHART_DAILYHL(即daily表?)的统计结果更新到summary表。
所以,我们可能只需要在循环中将每个CSV文件的数据插入到daily表(SPC_CHART_DAILYHL?),然后在循环结束后,执行修数操作,更新summary表(DAILY_CHART_SUMMARY)。
然而,问题中修数函数的SQL语句中涉及多个参数,这些参数在循环中需要收集,以便在循环结束后使用。参数包括:load_time, product, chart_type, Object_type(注意:在修数SQL中,summary表的字段是DEPARTMENT,而参数名为:Object_type,所以注意命名一致)。
因此,我们需要:
在循环中,除了插入数据到daily表,还要收集每个文件(或每次循环)的参数值,存储在一个列表中,以便循环结束后使用。
具体步骤:
1. 初始化一个列表(例如param_list)来保存每次循环的参数。
2. 循环处理每个CSV文件:
a. 读取CSV文件。
b. 插入到daily表(假设表名为SPC_CHART_DAILYHL)。
c. 从当前CSV文件或文件名中提取参数(load_time, product, chart_type, Object_type),或者从数据中提取?这里需要用户明确如何获取这些参数。假设这些参数可以从CSV文件中的某列得到,或者从文件名中解析,或者用户另有提供。由于问题没有具体说明,我们假设每次循环我们已知这些参数(比如从CSV的某行获取,或者从文件名中获取,或者作为循环变量的一部分)。这里我们假设这些参数已经知道,例如:
load_time = 当前时间或文件中的时间
product = 从文件名中解析的产品名
chart_type = 从文件名中解析的图表类型
Object_type = 从文件名中解析的部门
d. 将这四个参数作为一个元组添加到param_list中。
3. 循环结束后,我们得到了param_list,里面是每次循环的参数集合。
4. 然后,我们遍历param_list,对每组参数执行修数操作(即更新summary表)。
但是,注意:在循环中插入daily表的数据,在循环结束后立即更新summary表,这要求整个循环在一个数据库事务中?还是分开?根据需求,我们可以每处理一个文件就更新summary表,但问题要求在循环结束后进行。所以我们在循环中只收集参数,循环结束后再更新。
然而,更新summary表的SQL语句是:
UPDATE DAILY_CHART_SUMMARY dcs
SET dcs.ABNORMAL_COUNT = (
SELECT COUNT(scd.HLTYPE)
FROM SPC_CHART_DAILYHL scd
WHERE scd.LOAD_TIME = TO_DATE(:load_time, 'yyyy-MM-dd HH24:MI:SS')
AND scd.PRODUCT_FAMILY = :product
AND scd.CHART_TYPE = :chart_type
AND scd.DEPARTMENT = :Object_type
)
WHERE dcs.LOAD_TIME = TO_DATE(:load_time, 'yyyy-MM-dd HH24:MI:SS')
AND dcs.PRODUCT_FAMILY = :product
AND dcs.CHARTTYPE = :chart_type -- 注意:summary表中是CHARTTYPE,而daily表中是CHART_TYPE
AND dcs.DEPARTMENT = :Object_type;
注意:这里两个表的字段名不完全一致(CHART_TYPE vs CHARTTYPE),所以我们在写SQL时要小心。
另外,我们也可以使用MERGE语句来更新,但这里只需要更新一个字段,用UPDATE即可。
但是,我们还需要考虑:如果summary表中没有对应的记录怎么办?那么UPDATE将不会更新任何行。所以,我们需要确保summary表在插入daily表之前已经有相应的记录?或者我们使用MERGE来更新或插入?但是问题中只要求更新。
根据问题描述,我们只更新ABNORMAL_COUNT字段,所以假设summary表中已经存在对应的记录(由其他过程插入)。如果不存在,则更新0行,也不会有错误。
因此,我们可以在循环结束后,遍历参数列表,对每组参数执行上述UPDATE。
代码框架:
步骤1:连接数据库(使用用户已有的连接)
步骤2:定义CSV文件列表
步骤3:初始化参数列表
步骤4:循环处理每个CSV文件
读取CSV -> 插入daily表 -> 提取参数并保存
步骤5:循环结束后,遍历参数列表,对每组参数执行UPDATE
但是,注意:在插入daily表时,我们可能插入了多行数据,而每个CSV文件对应一组参数(即一个load_time, product, chart_type, Object_type组合),那么我们在更新summary表时,每组参数对应更新summary表中的一行。
代码示例:
假设我们使用cx_Oracle连接,并且已经建立了conn和cursor。
注意:在插入daily表时,我们使用引用[1]的方法(executemany)或引用[3]的方法(to_sql)。这里我们使用executemany,因为引用[1]已经给出了示例。
但是,由于我们还需要在插入daily表后收集参数,且参数可能要从CSV数据中提取(比如每个CSV文件中的所有行都有相同的product, chart_type, Object_type?),那么我们可以从第一行提取这些参数(假设整个文件这些参数相同)。
或者,如果每个CSV文件对应不同的参数,我们可以从文件名中解析,或者用户另外提供映射关系。这里我们假设每个CSV文件对应一组参数,并且这些参数可以通过函数从文件名或文件路径中解析出来。
我们定义一个函数来解析参数:
def parse_parameters_from_filename(file_path):
# 根据文件名解析出product, chart_type, Object_type
# 假设文件名格式为:product_charttype_department.csv
# 例如:A_product_B_chart_C_department.csv
# 这里只是示例,具体解析方式根据实际文件名而定
# 同时,load_time可以使用当前时间,或者从文件内容中获取,这里我们假设使用当前时间
import os
from datetime import datetime
filename = os.path.basename(file_path)
parts = filename.split('_')
product = parts[0]
chart_type = parts[1]
Object_type = parts[2]
load_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 或者从其他地方获取
return load_time, product, chart_type, Object_type
但是,注意:在修数SQL中,load_time是TO_DATE函数转换的,所以我们要确保传入的load_time字符串格式与SQL中的格式一致。
另外,在插入daily表时,我们也要插入这些参数对应的值。假设CSV文件中有多列,其中就包含这些字段?还是说这些字段不在CSV中,而是作为额外字段插入?这里需要明确。
根据修数SQL,daily表(SPC_CHART_DAILYHL)有字段:LOAD_TIME, PRODUCT_FAMILY, CHART_TYPE, DEPARTMENT, HLTYPE等。
因此,我们假设CSV文件中已经包含了这些字段(至少包含HLTYPE,因为我们要统计它),但是LOAD_TIME, PRODUCT_FAMILY, CHART_TYPE, DEPARTMENT可能不在CSV中,而是由我们解析得到并添加到每一行。
所以,我们在读取CSV后,需要添加这些列。或者,我们可以在插入时在SQL语句中指定这些值。
因此,我们修改插入daily表的步骤:
读取CSV文件到df
解析参数:load_time, product, chart_type, Object_type
在df中添加新列:
df['LOAD_TIME'] = load_time # 注意:这里load_time是字符串,但数据库中是日期,所以我们需要转换为日期类型?或者用字符串插入,由数据库转换?
df['PRODUCT_FAMILY'] = product
df['CHART_TYPE'] = chart_type
df['DEPARTMENT'] = Object_type
然后,将整个df插入到daily表。
这样,在修数时,我们就能根据这些字段去统计。
所以,循环中的步骤:
for file_path in csv_files:
# 读取CSV
df = pd.read_csv(file_path)
# 解析参数
load_time, product, chart_type, Object_type = parse_parameters_from_filename(file_path)
# 添加参数列
df['LOAD_TIME'] = load_time
df['PRODUCT_FAMILY'] = product
df['CHART_TYPE'] = chart_type
df['DEPARTMENT'] = Object_type
# 将df插入到daily表(SPC_CHART_DAILYHL)
# 使用引用[1]的方法,注意先创建表(如果不存在)?或者表已经存在
# 假设表已经存在,我们只需要插入
# 将df转换为元组列表
# 注意:日期列我们转成了字符串,所以数据库需要能够转换,或者我们在这里转换为datetime对象
# 但引用[1]中使用了字符串,所以数据库表字段应该是日期类型,插入时用字符串,Oracle会自动转换(格式必须正确)
# 这里load_time的格式是'%Y-%m-%d %H:%M:%S',而Oracle的TO_DATE也是这个格式,所以可以。
# 将df的每一行转换为元组
# 先确保列的顺序与表一致
# 假设我们不知道列顺序,但我们可以按照表定义的顺序,这里我们假设df的列顺序与表一致,但因为我们新增了列,所以需要调整列顺序?
# 为了安全,我们可以按照表定义的列顺序来排列df的列。但这里我们不知道表定义,所以假设表包含所有df的列,以及我们新增的列。
# 使用executemany插入
# 先构造插入语句
# 引用[1]的方法:
# cursor.execute('DROP TABLE IF EXISTS {}'.format(table_name)) 我们不删除表,所以去掉
# cursor.execute('CREATE TABLE {}({})'.format(table_name,make_table_sql(df))) 我们假设表已存在,所以去掉建表
# 将日期列转为字符串(如果已经是字符串则跳过)
# 这里我们已经在前面将LOAD_TIME设为字符串,所以不需要再转换(除非其他日期列)
# 将数据转为元组列表
values = df.values.tolist()
s = ','.join(['%s' for _ in range(len(df.columns))])
sql = f"INSERT INTO SPC_CHART_DAILYHL ({','.join(df.columns)}) VALUES ({s})"
cursor.executemany(sql, values)
# 保存参数
param_list.append((load_time, product, chart_type, Object_type))
注意:这里使用executemany插入大量数据时,如果数据量很大,可能会造成内存问题,也可以考虑分块插入。
然后,循环结束后:
for params in param_list:
load_time, product, chart_type, Object_type = params
# 执行更新summary表的SQL
update_sql = """
UPDATE DAILY_CHART_SUMMARY dcs
SET dcs.ABNORMAL_COUNT = (
SELECT COUNT(scd.HLTYPE)
FROM SPC_CHART_DAILYHL scd
WHERE scd.LOAD_TIME = TO_DATE(:1, 'yyyy-MM-dd HH24:MI:SS')
AND scd.PRODUCT_FAMILY = :2
AND scd.CHART_TYPE = :3
AND scd.DEPARTMENT = :4
)
WHERE dcs.LOAD_TIME = TO_DATE(:1, 'yyyy-MM-dd HH24:MI:SS')
AND dcs.PRODUCT_FAMILY = :2
AND dcs.CHARTTYPE = :3 -- 注意字段名
AND dcs.DEPARTMENT = :4
"""
cursor.execute(update_sql, (load_time, product, chart_type, Object_type))
# 注意:这里使用了位置参数(:1, :2, ...)也可以使用命名参数,但cx_Oracle的命名参数需要以字典形式传入,这里为简单使用位置参数。
conn.commit() # 提交事务
但是,这里有一个问题:在同一个事务中,我们刚刚插入到daily表的数据,在同一个事务中是可以被后面的UPDATE查询到的。所以,我们在循环开始前应该开启事务,循环结束后提交。或者,如果循环中每次提交,那么更新时就能看到已提交的数据。但根据需求,我们希望在循环结束后进行更新,所以整个操作应该在一个事务中?或者分开事务?
这里,如果数据量很大,我们可能需要在循环中分批提交,以避免undo过大。但是,如果循环中提交了,那么更新summary表时就能看到已经提交的数据,这样是没问题的。所以,我们可以在每次插入daily表后提交,然后在更新summary表时再提交一次(更新summary表时,每组参数更新一次,可以每更新一次提交,或者全部更新后提交)。
但是,用户要求“在for循环结束后进行summary表的修数操作”,所以我们可以这样:
循环中每插入一个文件就提交一次(这样避免长时间未提交导致锁表或undo过大),然后循环结束后更新summary表,再提交更新。
但是,这样在更新summary表时,daily表的数据已经提交,所以可以查询到。
因此,我们可以在循环内每插入一个文件就提交,然后循环结束后更新summary表,再提交更新。或者,如果希望整个操作原子性,则最后一起提交。这里根据业务需求选择。
我们假设允许每插入一个文件就提交,更新summary表也立即提交(或一起提交)。这里我们在循环内插入并提交,循环结束后更新summary表再提交。
修改:
for file_path in csv_files:
... 插入daily表
cursor.executemany(sql, values)
conn.commit() # 插入一个文件提交一次
for params in param_list:
... 更新summary表
cursor.execute(update_sql, params)
conn.commit() # 更新一组参数提交一次,或者全部更新完再提交?这里我们可以选择全部更新完再提交,因为更新操作可能很快。
但是,如果更新操作很多,也可以每更新一组参数提交一次,这样避免大事务。
另外,注意:在更新summary表时,我们使用了相同的参数(load_time, product, chart_type, Object_type)去查询daily表,然后更新summary表。这里我们假设daily表中已经插入了这些参数对应的数据,并且我们刚刚提交了,所以肯定可以查询到。
但是,如果多个进程同时操作,可能会有并发问题。这里我们假设是单进程。
最后,关于参数传递:在更新summary表的SQL中,我们使用了位置参数(:1, :2, :3, :4),在cursor.execute时传入一个元组,元组的顺序就是1,2,3,4对应的值。
注意:在解析参数时,我们得到的load_time是字符串,而update_sql中使用了TO_DATE转换,所以没问题。
但是,在插入daily表时,我们插入的LOAD_TIME列是字符串,而数据库表是日期类型,Oracle会自动转换(要求字符串格式正确)。所以,我们保证load_time字符串的格式是'yyyy-MM-dd HH24:MI:SS'。
总结代码结构:
import pandas as pd
import cx_Oracle
# 连接数据库(假设已有conn和cursor)
csv_files = [...] # 文件列表
param_list = [] # 用于保存参数
for file_path in csv_files:
df = pd.read_csv(file_path)
# 解析参数
load_time, product, chart_type, Object_type = parse_parameters_from_filename(file_path)
# 添加列
df['LOAD_TIME'] = load_time
df['PRODUCT_FAMILY'] = product
df['CHART_TYPE'] = chart_type
df['DEPARTMENT'] = Object_type
# 准备插入
values = df.values.tolist()
cols = ','.join(df.columns)
s = ','.join([':%d' % (i+1) for i in range(len(df.columns))]) # 使用命名参数占位符,但cx_Oracle也支持数字占位符
# 注意:cx_Oracle的占位符是:1, :2, ...,但也可以不用数字而用名字,这里我们用数字
# 但是,在executemany中,我们使用数字占位符,传入的元组列表中的每个元组对应一行,每个元组的元素顺序与列顺序一致
sql = f"INSERT INTO SPC_CHART_DAILYHL ({cols}) VALUES ({s})"
cursor.executemany(sql, values)
conn.commit() # 提交插入
param_list.append((load_time, product, chart_type, Object_type))
# 更新summary表
update_sql = """
UPDATE DAILY_CHART_SUMMARY dcs
SET dcs.ABNORMAL_COUNT = (
SELECT COUNT(scd.HLTYPE)
FROM SPC_CHART_DAILYHL scd
WHERE scd.LOAD_TIME = TO_DATE(:1, 'yyyy-MM-dd HH24:MI:SS')
AND scd.PRODUCT_FAMILY = :2
AND scd.CHART_TYPE = :3
AND scd.DEPARTMENT = :4
)
WHERE dcs.LOAD_TIME = TO_DATE(:1, 'yyyy-MM-dd HH24:MI:SS')
AND dcs.PRODUCT_FAMILY = :2
AND dcs.CHARTTYPE = :3
AND dcs.DEPARTMENT = :4
"""
for params in param_list:
cursor.execute(update_sql, params)
conn.commit() # 提交更新
注意:在更新SQL中,我们使用了相同的参数两次(一次在子查询,一次在WHERE条件),所以一个参数元组有四个元素,在SQL中我们通过:1,:2,:3,:4来引用,并且在子查询和WHERE条件中重复使用,所以参数元组中的每个元素被多次使用。这是允许的。
但是,这里有一个潜在问题:如果某个参数组在daily表中没有数据,那么子查询会返回0,然后更新summary表中对应的行的ABNORMAL_COUNT为0。这可能是期望的。
另外,如果summary表中没有对应的行,那么更新不会影响任何行(不会报错)。
最后,我们还需要处理异常,添加try-except块,以及关闭连接等,这里省略。
关于parse_parameters_from_filename函数,用户需要根据实际文件名格式来实现。
这样,我们就实现了用户的需求。
注意:如果数据量非常大,可以考虑使用批量更新(比如将多个参数组合成一个SQL,用OR条件,但这样可能效率不高),或者使用绑定变量数组(cx_Oracle的executemany)来更新,但这里更新操作次数等于参数组数,通常不会太多,所以逐个更新也可以。
另外,在插入daily表时,如果数据量很大,executemany可能会慢,可以考虑使用引用[2]的LOAD DATA方法,但LOAD DATA需要文件在数据库服务器上,或者使用客户端加载(需要配置)。这里我们使用executemany,因为文件在客户端。
如果文件很大,也可以考虑分块插入,避免内存问题。
以上代码框架,用户可以根据实际情况调整。
</think>
下面是根据您的需求设计的Python代码框架,整合了CSV导入、数据修数和参数传递功能:
```python
import pandas as pd
import cx_Oracle
from datetime import datetime
# 数据库连接配置
conn = cx_Oracle.connect('user/password@host:port/service_name')
cursor = conn.cursor()
def repair_data(load_time, product, chart_type, object_type):
"""修数函数:更新summary表的异常计数"""
update_sql = """
UPDATE DAILY_CHART_SUMMARY dcs
SET dcs.ABNORMAL_COUNT = (
SELECT COUNT(scd.HLTYPE)
FROM SPC_CHART_DAILYHL scd
WHERE scd.LOAD_TIME = TO_DATE(:load_time, 'yyyy-MM-dd HH24:MI:SS')
AND scd.PRODUCT_FAMILY = :product
AND scd.CHART_TYPE = :chart_type
AND scd.DEPARTMENT = :object_type
)
WHERE dcs.LOAD_TIME = TO_DATE(:load_time, 'yyyy-MM-dd HH24:MI:SS')
AND dcs.PRODUCT_FAMILY = :product
AND dcs.CHARTTYPE = :chart_type
AND dcs.DEPARTMENT = :object_type
"""
params = {
'load_time': load_time,
'product': product,
'chart_type': chart_type,
'object_type': object_type
}
cursor.execute(update_sql, params)
conn.commit()
def csv_to_db(file_path, table_name, param_store=[]):
"""CSV导入数据库函数"""
try:
df = pd.read_csv(file_path)
# 添加时间戳列
load_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
df['LOAD_TIME'] = load_time
# 动态生成插入SQL
columns = ','.join(df.columns)
placeholders = ','.join([f":{i+1}" for i in range(len(df.columns))])
# 批量插入数据
sql = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
cursor.executemany(sql, df.values.tolist())
conn.commit()
# 存储参数用于后续修数 (从数据中提取关键字段)
if 'PRODUCT_FAMILY' in df.columns and 'CHART_TYPE' in df.columns and 'DEPARTMENT' in df.columns:
sample_row = df.iloc[0]
param_store.append({
'load_time': load_time,
'product': sample_row['PRODUCT_FAMILY'],
'chart_type': sample_row['CHART_TYPE'],
'object_type': sample_row['DEPARTMENT']
})
print(f"成功导入 {len(df)} 行到 {table_name}")
except Exception as e:
conn.rollback()
print(f"导入失败: {str(e)}")
# 主处理流程
if __name__ == "__main__":
# 存储修数参数的列表
repair_params = []
# 示例文件列表 (根据实际情况修改)
csv_files = [
{'path': 'daily_data1.csv', 'table': 'SPC_CHART_DAILYHL'},
{'path': 'summary_data1.csv', 'table': 'DAILY_CHART_SUMMARY'},
# 添加更多文件...
]
# 循环处理CSV文件
for file_info in csv_files:
csv_to_db(file_info['path'], file_info['table'], repair_params)
# 循环结束后执行修数操作
print("\n开始修数操作...")
for params in repair_params:
try:
repair_data(
load_time=params['load_time'],
product=params['product'],
chart_type=params['chart_type'],
object_type=params['object_type']
)
print(f"已更新 {params['product']}-{params['chart_type']} 的异常计数")
except Exception as e:
print(f"修数失败: {str(e)}")
cursor.close()
conn.close()
print("所有操作完成")
```
### 关键实现说明
1. **参数传递机制**:
- 在`csv_to_db`函数中添加`param_store`列表参数
- 从CSV的首行提取关键字段(产品/图表类型/部门)
- 将参数封装为字典存储:`{'load_time', 'product', 'chart_type', 'object_type'}`
- 循环结束后遍历参数列表执行修数
2. **时间戳处理**:
- 使用`datetime.now()`生成统一时间戳
- 格式化为Oracle日期格式:`YYYY-MM-DD HH24:MI:SS`
- 同时插入到daily和summary表保持时间一致
3. **动态SQL生成**:
```python
# 根据CSV列名动态生成
columns = ','.join(df.columns)
placeholders = ','.join([f":{i+1}" for i in range(len(df.columns))])
sql = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
```
4. **异常处理**:
- 每个文件导入使用独立事务
- 单文件失败自动回滚不影响其他文件
- 修数操作单独捕获异常
### 性能优化建议
1. **批量提交优化**:
```python
# 每处理1000行提交一次
batch_size = 1000
for i in range(0, len(df), batch_size):
batch = df[i:i+batch_size]
cursor.executemany(sql, batch.values.tolist())
conn.commit()
```
2. **使用绑定变量提升效率**:
```python
# 预编译SQL语句
cursor.prepare(sql)
cursor.executemany(None, df.values.tolist())
```
3. **日期格式优化**:
```python
# 直接使用Oracle日期对象
from datetime import datetime
df['LOAD_TIME'] = [datetime.now() for _ in range(len(df))]
```
4. **并行处理(可选)**:
```python
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=4) as executor:
futures = [executor.submit(csv_to_db, f['path'], f['table'], repair_params)
for f in csv_files]
for future in concurrent.futures.as_completed(futures):
future.result()
```
### 参数传递示意图
```mermaid
graph TD
A[CSV文件] --> B{提取关键参数}
B -->|PRODUCT_FAMILY| C[参数存储]
B -->|CHART_TYPE| C
B -->|DEPARTMENT| C
C --> D[循环结束]
D --> E{遍历参数列表}
E --> F[执行修数函数]
F -->|UPDATE| G[DAILY_CHART_SUMMARY]
```
### 注意事项
1. **字段映射**:
- 确保CSV包含`PRODUCT_FAMILY`, `CHART_TYPE`, `DEPARTMENT`列
- 若字段名不同,修改`csv_to_db`中的提取逻辑
2. **日期兼容性**:
- Oracle日期格式需与`TO_DATE`匹配
- 遇到格式错误时可使用:
```python
df['DATE_COL'] = pd.to_datetime(df['DATE_COL']).dt.strftime('%Y-%m-%d %H:%M:%S')
```
3. **事务控制**:
- 大型操作建议分批次提交
- 使用`conn.autocommit = False`显式控制事务
4. **内存管理**:
- 大文件使用`chunksize`分批读取
```python
for chunk in pd.read_csv('large.csv', chunksize=10000):
process_chunk(chunk)
```
此方案实现了:
1. 循环导入多CSV到不同表
2. 自动提取并存储修数参数
3. 循环结束后批量更新summary表
4. 完备的错误处理和事务控制