Время прочтения: 3 мин.

Часто в работе нашего подразделения мы сталкиваемся с неприятной особенностью выгрузок CSV через инструмент PLSQL Developer – «сохранение в файл csv результата выполнения запроса».

Для дальнейшего анализа выгруженный файл csv обычно требуется загрузить в pandas.dataframe или в другую СУБД.

При попытке загрузки файла мы сталкиваемся с неприятными ошибками вроде нечитаемых символов, которые pandas не может соотнести с таблицей кодировки:

OSError: Initializing from file failed.

Исследуем вопрос, проведем анализ данных csv файла.

Прочитаем несколько срок из файла и выведем результат в консоль:

Код:

if __name__ == '__main__':
    with open(r'C:\Users\user\Desktop\editOBScsv\1.csv', 'r', encoding='utf-8',
              errors='ignore') as fo:
        c = 0
        for row in fo:
            print(row)
            c += 1
            if c == 2:
                break

— в данном случае указываем обязательный атрибут errors=’ignore’, который помогает игнорировать символы, не совпадающие с таблицей кодировки.

Вывод:

i?"ID кредита";"Сумма кредита….
"363092205X474";"2505600,00

Вывод в консоль в бинарном варианте чтения:

if __name__ == '__main__':
    with open(r'C:\Users\Desktop\editOBScsv\нулевые графики.csv', 'rb') as fo:
        c = 0
        for row in fo:
            print(row)
            c += 1
            if c == 1:
                break

Вывод:

b'i\xbb?"ID \xd0\xba\xd1\x80\xd0\xb5\xd0\xb4\xd0\xb8\xd1\x82\xd0\xb0";"\xd0\xa1\xd1\x83\xd0\xbc\xd0\xbc\xd0\xb0 \xd0\xba\xd1\x80\xd0\xb5\xd0\xb4\xd0\xb8\xd1\x82\xd0\xb0";"\

Обратите внимание на первые 2 символа ‘i?’ (бинарный вариант i\xbb?). Именно они мешают методу pandas.read_csv корректно прочитать файл в DataFrame, а так же препятствуют загрузки файла в СУБД.

Далее рассмотрим три варианта решения.

Вариант первый

Если файл размера до 1.2 ГБ – файл открывается стандартным блокнотом.

Решение: Открыть файл – удалить первые два символа – сохранить и использовать в pandas/СУБД.

НО! Файлы более 1.2ГБ, блокнот, Notepad ++   —   не откроют.

Вариант второй

Установить навороченный текстовый тру редактор, например – EmEditor работающий с большими текстовыми файлами. Открыть файл – удалить первые два символа – сохранить и использовать в pandas/СУБД.

Вариант третий для знающих Python

Csv – это текстовый файл, последовательность символов.
Решение, предложенное ниже использует встроенные библиотеки. Оно заключается в построчном чтении строк, при этом первая строка обрезается с левой стороны на 2 символа следующей конструкцией row = row[2:].

На выходе получаем обработанный файл, сохраненный в указанной директории.

pathRead – указываем путь к файлу, содержащему недопустимые символы

pathWrite – указываем пусть сохранения обработанного файла Код:

import time

if __name__ == '__main__':
    prTimeStart = time.process_time()
    cf = 0
    
    pathRead = r'C:\Users\Desktop\editOBScsv\нулевые графики.csv'
    pathWrite = r'C:\Users\Desktop\editOBScsv\out.csv'
    
    with open(pathRead, 'r', encoding='utf-8', errors='ignore') as fo:
        with open(pathWrite, 'w', encoding='utf-8') as fw:
            for row in fo:
                cf += 1
            print('Row counts = %d' % cf)
            fo.seek(0)
            print(f'Starting to copy and past rows in the new file..')
            cf = 0
            for row in fo:
                if cf == 0:
                    print('First row before changing:\n%s' % row)
                    row = row[2:]
                    print('First row after changing:\n%s' % row)
                    cf += 1
                fw.writelines(row)
            print('End copy row in new file.')
    print('Time executed copy/past = %f' % (time.process_time() - prTimeStart))
C:\Anaconda3\python.exe C:/Users/PycharmProjects/editODScsv.py
Row counts = 3696862
Starting to copy and past rows in the new file..
First row before changing:
i?"ID кредита";"Сумма кредита….

First row after changing:
"ID кредита";"Сумма кредита…..

End copy row in new file.
Time executed copy/past = 275.781250

Process finished with exit code 0

Обработанный файл можно использовать в pandas/СУБД.