2016-02-02 3 views
1

Я пытаюсь извлечь некоторые устаревшие данные с сервера Teradata, но некоторые из записей содержат странные символы, которые не регистрируются на python, такие как «U + ffffffc2».Нужно пропустить строку, содержащую «Ошибка значения»

В настоящее время

  1. Я использую pyodbc для извлечения данных из Teradata

  2. Размещение результатов в Numpy массива (потому что, когда я положил его прямо в панд, он интерпретирует все столбцы как один столбец строки типа)

  3. Затем я превращаю массив numpy в рамку данных pandas, чтобы изменить такие параметры, как Decimal («09809») и Date («2015,11,14»), в [09809, "11,14,2015"]

  4. Тогда я пытаюсь записать его в файл, в котором происходит эта ошибка

    ValueError: символ U + ffffffc2 не в диапазоне [U + 0000; U + 10FFFF]

У меня нет доступа для редактирования этой информации, так что с точки зрения клиента, что я могу сделать, чтобы пропустить или, предпочтительно, удалить символ перед записью пытается записать его в файл и получить ошибку?

В настоящее время у меня есть блок «try and except» для пропуска запросов с ошибочными данными, но я должен запрашивать данные в строках строк не менее 100. Так что, если я просто пропущу его, я потеряю 100 или более строк вовремя. Однако, как я уже упоминал ранее, я бы предпочел сохранить линию, но удалить персонажа.

Вот мой код. (Вы можете указать, какие плохие методы, как хорошо!)

#Python 3.4 
#Python Teradata Extraction 
#Created 01/28/16 by Maz Baig 

#dependencies 
import pyodbc 
import numpy as np 
import pandas as pd 
import sys 
import os 
import psutil 
from datetime import datetime 


#create a global variable for start time 
start_time=datetime.now() 
#create global process variable to keep track of memory usage 
process=psutil.Process(os.getpid()) 

def ResultIter(curs, arraysize): 
     #Get the specified number of rows at a time 
     while True: 
       results = curs.fetchmany(arraysize) 
       if not results: 
         break 
       #for result in results: 
       yield results 

def WriteResult(curs,file_path,full_count): 
     rate=100 
     rows_extracted=0 
     for result in ResultIter(curs,rate): 
       table_matrix=np.array(result) 
       #Get shape to make sure its not a 1d matrix 
       rows, length = table_matrix.shape 
       #if it is a 1D matrix, add a row of nothing to make sure pandas doesn't throw an error 
       if rows < 2: 
         dummyrow=np.zeros((1,length)) 
         dummyrow[:]=None 
       df = pd.DataFrame(table_matrix) 
       #give the user a status update 
       rows_extracted=rows+rows_extracted 
       StatusUpdate(rows_extracted,full_count) 
       with open(file_path,'a') as f: 
         try: 
           df.to_csv(file_path,sep='\u0001',encoding='latin-1',header=False,index=False) 
         except ValueError: 
           #pass afterwards 
           print("This record was giving you issues") 
           print(table_matrix) 
           pass 
     print('\n') 
     if (rows_extracted < full_count): 
       print("All of the records were not extracted") 
       #print the run durration 
       print("Duration: "+str(datetime.now() - start_time)) 
       sys.exit(3) 
     f.close() 




def StatusUpdate(rows_ex,full_count): 
     print("          ::Rows Extracted:"+str(rows_ex)+" of "+str(full_count)+" | Memory Usage: "+str(process.memory_info().rss/78 



def main(args): 
     #get Username and Password 
     usr = args[1] 
     pwd = args[2] 
     #Define Table 
     view_name=args[3] 
     table_name=args[4] 
     run_date=args[5] 
     #get the select statement as an input 
     select_statement=args[6] 
     if select_statement=='': 
       select_statement='*' 
     #create the output filename from tablename and run date 
     file_name=run_date + "_" + table_name +"_hist.dat" 
     file_path="/prod/data/cohl/rfnry/cohl_mort_loan_perfnc/temp/"+file_name 
     if (not os.path.exists(file_path)): 
       #create connection 
       print("Logging In") 
       con_str = 'DRIVER={Teradata};DBCNAME=oneview;UID='+usr+';PWD='+pwd+';QUIETMODE=YES;' 
       conn = pyodbc.connect(con_str) 
       print("Logged In") 

       #Get number of records in the file 
       count_query = 'select count (*) from '+view_name+'.'+table_name 
       count_curs = conn.cursor() 
       count_curs.execute(count_query) 
       full_count = count_curs.fetchone()[0] 

       #Generate query to retrieve all of the table data 
       query = 'select '+select_statement+' from '+view_name+'.'+table_name 
       #create cursor 
       curs = conn.cursor() 
       #execute query 
       curs.execute(query) 
       #save contents of the query into a matrix 
       print("Writting Result Into File Now") 
       WriteResult(curs,file_path,full_count) 
       print("Table: "+table_name+" was successfully extracted") 
       #print the scripts run duration 
       print("Duration: "+str(datetime.now() - start_time)) 
       sys.exit(0) 
     else: 
       print("AlreadyThere Exception\nThe file already exists at "+file_path+". Please remove it before continuing\n") 
       #print the scripts run duration 
       print("Duration: "+str(datetime.now() - start_time)) 
       sys.exit(2) 

main(sys.argv) 

Спасибо,

Маз

+0

'ffffffc2' is' 4294967234', где U + ffffffc2, исходящий из? –

+0

Я уверен, что это означает '\ uffffffc2', которого нет. – Maz

+0

Да 'U + ffffffc' не является допустимой точкой кода юникода, но hex является, каков контекст того, откуда он? –

ответ

2

Если у вас есть только 4 байта Юникода точек, дающих ошибку, это, вероятно, может помочь. Одним из решений является зарегистрировать обработчик ошибок с помощью codecs.register_error, который будет отфильтровывать точки ошибок, а затем просто попытаться расшифровать:

import codecs 

def error_handler(error): 
    return '', error.end+6 

codecs.register_error('nonunicode', error_handler) 

b'abc\xffffffc2def'.decode(errors='nonunicode') 
# gives you 'abcdef' which's exactly what you want 

Вы можете futher обработчик улучшения обнаружения поймать более сложных ошибок, см https://docs.python.org/3/library/exceptions.html#UnicodeError и https://docs.python.org/3/library/codecs.html#codecs.register_error для получения более подробной информации

Смежные вопросы