Категории


30 июня 2018 г. 12:46 (ред. 30 июня 2018 г. 13:27)
О новом приложении, позволяющем читать dbf-файлы.
.dbf — изначально формат представления баз данных dBase, насчитывающий уже более 30 лет истории, используемый и поныне.

Например, в этом формате (наряду с другими) представлена ФИАС — Федеральная информационная адресная система. Его же использует для некоторых своих выгрузок Центральный банк РФ.

На заметку
За годы, прошедшие с момента появления формата, он не раз модифицировался и адаптировался под нужды различных СУБД, добавлялась поддержка новых типов данных, шифрования и пр.

И вот, недавно мне понадобилась незатейливая dbf-читалка. Требования были минимальными, чтобы: 1. работала под третьим Питоном; 2. обладала удобными интерфейсами для чтения файлов (запись при этом не требуется); 3. не кушала много памяти.

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

Из симпатичных остался, пожалуй, только dbfread, имеющий солидный арсенал возможностей.
Но, вот что меня смутило: 1. интерфейс чтения файлов, запрятанный внутрь инициализатора и итерирования рядов; 2. представление рядов (по умолчанию) в виде упорядоченных словарей. Кабы не это — взял бы не раздумывая.

А так пришлось ваять своё: dbf_light.

dbf_light — та самая незатейливая dbf-читалка. Ничего особо выдающегося не делает, но:

1. Работает под Python 3;
2. Читает многие .dbf (поддержка формата FoxPro не отлажена, потому отключена);
3. Для открытия файлов использует уже классическую парадигму с менеджером контекста;
4. Из-за предыдущего пункта имеет возможность (и инструмент) для чтения .dbf прямо из zip-архива;
5. Ряды представлены в виде именованных кортежей;
6. Считывает данные итеративно по мере необходимости;
7. Если не указано иное (принудительно, либо в самом файле), используется кодировка cp866 (часто встречающаяся в наших .dbf, привет Академия Наук СССР);
8. Предлагает интерфейс командной строки, позволяющий как получить общую информацию о файле, так и вывести имеющиеся записи в консоль.

Код выглядит примерно так:

    from dbf_light import Dbf


with Dbf.open('some.dbf') as dbf:

for field in dbf.field:
print('Поле: %s' % field)

print('Всего записей (%s):' % dbf.prolog.records_count)

for row in dbf:
print(row)

# Читаем из zip:
with Dbf.open_zip('some.dbf', 'here/myarch.zip') as dbf:
...

Интерфес командной строки удобен, когда хочется понять, что внутри файла:

    $ dbf_light describe myfile.dbf
$ dbf_light show myfile.dbf

Полное прочтение файла из архива КЛАДР (DOMA.dbf — 329,4 Мб, 3 137 521 рядов по 8 строковых полей) походит на моём домашнем компьютере за 50 секунд (62750 рядов/с), в пике отъедая 11,38 Мб (ru_maxrss). Результаты, кстати говоря, вполне сравнимы с dbfread.

Иногда поддерживаем ископаемые форматы.