IndexError: 索引超出范围:7

5

我正在使用一个名为Financial Data Quality Management Enterprise Edition (FDMEE)的Oracle EPM产品。我编写了一个Jython脚本来解析数据文件并将其推送到FDMEE产品模式中的自定义表中。

当我推送数据文件的子集时,它可以正常工作。但是当我解析整个数据文件时,会出现错误IndexError: index out of range: 7。

以下是我收到的错误信息:

File "\\vmhodvesip4\D$\SVESI7\Custom\FDMEEApps\BFRVN/data/scripts/event/BefImport.py", line 5, in <module>

    if row[7]=='JAN':

IndexError: index out of range: 7

以下是我使用的代码:
import csv

recReader = csv.reader(open('D:/SVESI7/Custom/FDMEEApps/BFRVN/inbox/BF_Reven_Load/Test03big.txt'), delimiter='!')
for row in recReader:
    if row[7]=='JAN':
        period_num = '1'
    elif row[7]=='FEB':
        period_num = '2'
    elif row[7]=='MAR':
        period_num = '3'
    elif row[7]=='APR':
        period_num = 4
    elif row[7]=='MAY':
        period_num = 5
    elif row[7]=='JUN':
        period_num = 6
    elif row[7]=='JUL':
        period_num = 7
    elif row[7]=='AUG':
        period_num = 8
    elif row[7]=='SEP':
        period_num = 9
    elif row[7]=='OCT':
        period_num = 10
    elif row[7]=='NOV':
        period_num = 11
    elif row[7]=='DEC':
        period_num = 12
    else:
        period_num = 'skip'

    if period_num != 'skip':
        params1 = ['batch_plnapps_oi',row[7],period_num,'20' + row[1][-2:],row[2], row[3], row[4], row[5], row[6], row[8], row[9], row[10], row[11], round(row[12],12)]
        ins_stmt1 = "insert into aif_open_interface(batch_name,period,period_num,year,col03,col04,col05,col06,col07,col09,col10,col11,col12,amount) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
        fdmAPI.executeDML(ins_stmt1,params1,False)

fdmAPI.commitTransaction()

这个错误报告说你没有列表的第8个元素。期望的输出是什么?检查一下并尝试回溯。 - Ricardo Silveira
嗨@RicardoSilveira,感谢您的评论。预期输出是将数据从文件推送到产品数据库中的自定义模式中的表中。如果我使用数据子集,则代码执行良好,但如果我使用较大的数据集(具有类似的数据结构/格式),则会出现IndexError。同时,我正在使用pandas进行处理,感谢您的参考。 - Gautam TP
@Connor 谢谢你提供的参考,我正在阅读中。 - Gautam TP
当出现错误时,row的值是多少? - Barmar
那并没有回答我的问题。你需要在row出现错误时查看它,并找出为什么它没有预期的字段数。 - Barmar
显示剩余6条评论
2个回答

2

受影响的行显然少于8列。请尝试使用try/except块进行调试:

for n, row in enumerate(recReader, start=1):
    try:
        month = row[7]
    except:
        print('Row {0}: {1}'.format(n, row))

作为额外奖励,这里有一种更高效的编写代码的方法:
months = {'JAN': 1, 'FEB': 2, 'MAR': 3, 'APR': 4, 'MAY': 5, 'JUN': 6, 
          'JUL': 7, 'AUG': 8, 'SEP': 9, 'OCT':10, 'NOV': 11, 'DEC': 12]
for row in recReader:
    month = row[7]
    period_num = months.get(month, None)

    if period_num:
        params1 = ['batch_plnapps_oi', row[7], period_num, '20' + row[1][-2:], row[2], row[3], row[4], row[5], row[6], row[8], row[9], row[10], row[11], round(row[12], 12)]
        ins_stmt1 = "INSERT INTO aif_open_interface(batch_name, period, period_num, year, col03, col04, col05, col06, col07, col09, col10, col11, col12, amount) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
        fdmAPI.executeDML(ins_stmt1, params1, False)

fdmAPI.commitTransaction()

1
谢谢亚历山大的编辑!正在测试代码,会告诉你最新进展。 - Gautam TP
你应该使用字典来存储月份,而不是使用 index()。可以像这样定义一个字典:months = {'JAN': 1, 'FEB': 2,...},然后在循环中使用 for row in recReader: period_num = months.get(row[7], None)index() 每次需要遍历整个列表才能获取索引,而字典具有 O(1) 的查找效率。 - kylieCatt
@IanAuld 谢谢你的信息,Ian。我以前没有用过 dict,让我试试这个方法,会告诉你更新情况的。 - Gautam TP
不必为每一行执行查询,还有一种更有效的方法是批量处理信息,然后只需进行一次写入(假设您有足够的内存进行文件读取)。但这是另一个问题…… - Alexander

0

没有看到你的 .csv 文件,我们无法提供太多帮助,但是...

  1. 确保你的 csv 中每一行都有正确的格式
  2. 确保你的 csv 中最后一行不只是空格。
  3. 查看 csv.reader 的文档 中的可选参数,特别是 newline=''

嗨Vikram,感谢您的建议。该文件具有正确的格式,并且不以空格结尾(刚刚验证),如果数据集很小,则会从文件加载数据到产品表中,但是无法加载相同格式的更大数据集。 - Gautam TP
文件显然格式不正确,否则您不会收到此错误。该错误表示存在一行少于 8 个字段。 - Barmar
@Barmar 感谢Barmar/Vikram,这是一个相当大的文件,我已经从这个大文件中创建了大约7-8个单独的文件来进行测试,让我看看是否有一种方法可以验证整个文件是否存在格式不正确的行,这个数据文件是从一个名为Ab Initio的工具直接提取出来的,该工具在验证后转换文件,我会让你知道更新情况。 - Gautam TP
1
为什么不在脚本中添加 if len(row) < 8: print(row),这样你就可以看到错误的行了? - Barmar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接