Как я могу улучшить этот скрипт Python, чтобы заменить записи в файле DBF? - PullRequest
0 голосов
/ 02 мая 2018

У меня есть файл dbf с примерно 9 миллионами записей и размером 2,5 ГБ. Много места занято символьным полем размером 80, используемым для хранения 1 из примерно 10 различных символьных строк. Чтобы сэкономить на размере файла, я хочу заменить символьное поле целочисленным полем и использовать реляционную базу данных на более позднем этапе, чтобы получить полное символьное поле, если это необходимо.

В настоящее время у меня есть следующий скрипт Python, который использует библиотеку dbf (http://pythonhosted.org/dbf/). Сценарий, кажется, работает (проверено на меньшем файле dbf), но он работает в течение нескольких часов, когда я пытаюсь запустить его с полный файл DBF.

import dbf

tabel = dbf.Db3Table('dataset.dbf')
tabel.open()

with tabel:
 tabel.add_fields('newfield N(2, 0)')
 for record in tabel:
     if record.oldfield == 'string_a                                                                        ':
         dbf.write(record, newfield=1)
     elif record.oldfield == 'string_b                                                                        ':
         dbf.write(record, newfield=2)
     elif record.oldfield == 'string_c                                                                        ':
         dbf.write(record, newfield=3)
     elif record.oldfield == 'string_d                                                                        ':
         dbf.write(record, newfield=4)
     elif record.oldfield == 'string_e                                                                        ':
         dbf.write(record, newfield=5)
     elif record.oldfield == 'string_f                                                                        ':
         dbf.write(record, newfield=6)
     elif record.oldfield == 'string_g                                                                        ':
         dbf.write(record, newfield=7)
     elif record.oldfield == 'string_h                                                                        ':
         dbf.write(record, newfield=8)
     elif record.oldfield == 'string_i                                                                        ':
         dbf.write(record, newfield=9)
     elif record.oldfield == 'string_j                                                                        ':
         dbf.write(record, newfield=10)
     else:
         dbf.write(record, newfield=0)

dbf.delete_fields('dataset.dbf', 'oldfield')

Как вы можете видеть из кода, я новичок как в Python, так и в библиотеке dbf. Можно ли заставить этот скрипт работать более эффективно?

1 Ответ

0 голосов
/ 02 мая 2018

При добавлении и удалении полей в первую очередь создается резервная копия файла объемом 2,5 ГБ.

Лучше всего сделать новый dbf с той же структурой, что и у оригинала, за исключением этих двух полей; затем, когда вы копируете каждую запись, вносите изменения. Что-то вроде:

# lightly untested

old_table = dbf.Table('old_table.dbf')
structure = old_table.structure()
old_field_index = structure.index('oldfield')
structure = structure[:old_field_index] + structure[old_field_index+1:]
structure.append('newfield N(2,0)')
new_table = dbf.Table('new_name_here.dbf', structure)

with dbf.Tables(old_table, new_table):
    for rec in old_table:
        rec = list(rec)
        old_value = rec.pop(old_field_index)
        rec.append(<transform old_value into new_value>)
        new_table.append(tuple(rec))
...