Нужна помощь при ошибке DBF «Файл не найден» в Python при циклическом просмотре каталога? - PullRequest
0 голосов
/ 30 января 2020

Я хотел бы попросить помощи со скриптом Python, который должен l oop через каталог на диске. По сути, я хочу конвертировать более 10000 файлов DBF в CSV. Пока что я могу добиться этого для отдельного файла dbf , используя пакеты dbfread и Pandas. Выполнение этого сценария более 10000 отдельных раз, очевидно, неосуществимо, поэтому я хочу автоматизировать задачу, написав сценарий, который будет l oop через каждый dbf файл в каталоге.

Вот что я хотел бы сделать.

  • Определите каталог
  • Запишите для l oop, что будет l oop через каждый файл в в каталоге
  • Открыть только файл с расширением .dbf
  • Преобразовать в Pandas DataFrame
  • Определить имя для выходного файла
  • Записать в CSV и поместить файл в новый каталог

Вот код, который я использовал, чтобы проверить, могу ли я преобразовать отдельный файл .dbf в файл CSV.

from dbfread import DBF
import pandas as pd

table = DBF('Name_of_File.dbf')

#I originally kept receiving a unicode decoding error
#So I manually adjusted the attributes below

table.encoding = 'utf-8' # Set encoding to utf-8 instead of 'ascii'

table.char_decode_errors = 'ignore' #ignore any decode errors while reading in the file

frame  = pd.DataFrame(iter(table)) #Convert to DataFrame

print(frame) #Check to make sure Dataframe is structured proprely 

frame.to_csv('Name_of_New_File')

Приведенный выше код работал точно так, как и было задумано.

Вот мой код для l oop через каталог.

import os
from dbfread import DBF
import pandas as pd

directory = 'Path_to_diretory'

dest_directory = 'Directory_to_place_new_file'

for file in os.listdir(directory):

    if file.endswith('.DBF'):
        print(f'Reading in {file}...')
        dbf = DBF(file)
        dbf.encoding = 'utf-8'
        dbf.char_decode_errors = 'ignore'
        print('\nConverting to DataFrame...')
        frame = pd.DataFrame(iter(dbf))
        print(frame)
        outfile = frame.os.path.join(frame + '_CSV' + '.csv')
        print('\nWriting to CSV...')
        outfile.to_csv(dest_directory, index = False)
        print('\nConverted to CSV. Moving to next file...')

    else:
        print('File not found.')

Когда я запускаю этот код, я получаю ошибку DBFNotFound , которая говорит, что не удалось найти первый файл в каталоге. Поскольку я смотрю на свой код, я не уверен, почему это происходит, когда он работал в первом скрипте.

Это код из пакета dbfread , из которого создается исключение.

 class DBF(object):
   """DBF table."""
    def __init__(self, filename, encoding=None, ignorecase=True,
             lowernames=False,
             parserclass=FieldParser,
             recfactory=collections.OrderedDict,
             load=False,
             raw=False,
             ignore_missing_memofile=False,
             char_decode_errors='strict'):

        self.encoding = encoding
        self.ignorecase = ignorecase
        self.lowernames = lowernames
        self.parserclass = parserclass
        self.raw = raw
        self.ignore_missing_memofile = ignore_missing_memofile
        self.char_decode_errors = char_decode_errors

        if recfactory is None:
            self.recfactory = lambda items: items
        else:
            self.recfactory = recfactory

    # Name part before .dbf is the table name
        self.name = os.path.basename(filename)
        self.name = os.path.splitext(self.name)[0].lower()
        self._records = None
        self._deleted = None

        if ignorecase:
            self.filename = ifind(filename)
        if not self.filename:
            **raise DBFNotFound('could not find file {!r}'.format(filename))** #ERROR IS HERE
        else:
            self.filename = filename

Спасибо за предоставленную помощь.

1 Ответ

1 голос
/ 30 января 2020

os.listdir возвращает имена файлов внутри каталога, поэтому вы должны присоединить их к базовому пути, чтобы получить полный путь:

for file_name in os.listdir(directory):
    if file_name.endswith('.DBF'):
        file_path = os.path.join(directory, file_name)
        print(f'Reading in {file_name}...')
        dbf = DBF(file_path)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...