2015-09-17 29 views
5

Sto lavorando con un prodotto Oracle EPM chiamato Financial Data Quality Management Enterprise Edition (FDMEE). Ho scritto uno script Jython per analizzare un file di dati e inserirlo in una tabella personalizzata all'interno dello schema del prodotto FDMEE.IndexError: indice fuori intervallo: 7

Funziona correttamente quando sto spingendo un sottoinsieme di file di dati. Ma quando ho analizzare il tutto il file di dati, non riesce con l'errore IndexError: Indice fuori intervallo: 7.

seguito è il messaggio di errore che ricevo:

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 

seguito è il codice che uso:

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() 
+0

Questo errore rapporti non si dispone l'elemento 8 della lista. Qual è l'uscita prevista? Controllalo e prova a eseguire il traceback. –

+0

Inoltre, leggi la documentazione di Pandas [qui] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html) e lavora con i dataframes, sono molto meglio per questo scopo. –

+0

Non ho avuto molto tempo per guardare il tuo codice, ma ti suggerirei di usare Dict_Reader dal modulo csv in modo che tu possa guardare il nome della colonna in base alla colonna piuttosto che all'indice. Prova questo e potresti trovare una soluzione senza conoscere il problema – Connor

risposta

0

senza vedere il tuo .csv non possiamo davvero aiutare troppo, ma ...

  1. garantire che ogni riga nel csv ha il formato corretto
  2. Assicurati che l'ultima riga nel tuo csv non sia solo uno spazio bianco.
  3. Guarda i parametri opzionali in the documentation for csv.reader, specificamente newline=''
+0

Ciao Vikram, grazie per il suggerimento.Il file ha il formato corretto e non termina con uno spazio (appena verificato), carica i dati dal file alla tabella del prodotto se il set di dati è piccolo, ma non riesce a caricare un set di dati più grande dello stesso formato –

+0

il file ovviamente non ha il formato corretto o non si otterrebbe questo errore. L'errore indica che c'è una riga con meno di 8 campi. – Barmar

+0

@Barmar Grazie Barmar/Vikram, è un file abbastanza grande, ho creato circa 7-8 file separati da questo grande file per fare i test, fammi vedere un modo per verificare l'intero file se ci sono righe con formato errato, questo file di dati è un modulo di estrazione diretto uno strumento chiamato Ab Initio che trasforma il file dopo la convalida, ti consente di conoscere l'aggiornamento. –

2

Ci sono ovviamente meno di 8 colonne per riga interessata. Debug utilizzando un blocco try/except:

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

Come bonus, ecco un modo più efficiente per scrivere il codice:

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

Grazie Alexander per la modifica! Test del codice, ti farà sapere l'aggiornamento. –

+0

Dovresti usare un dict per i mesi invece di 'index()'. Qualcosa come 'months = {'JAN': 1, 'FEB': 2, ...}' quindi puoi semplicemente fare 'per riga in recReader: period_num = months.get (row [7], None)'. 'index()' ha bisogno di attraversare l'elenco ogni volta per ottenere l'indice mentre dicts ha O (1) lookup. – IanAuld

+0

@IanAuld Grazie per l'informazione Ian, Havenot ha usato il comando prima, lasciami provare a dettare questo approccio, ti farò sapere l'aggiornamento. –

Problemi correlati