Найти - Пользователи
Полная версия: Ошибка кодировки при работе с dbf-файлом
Начало » Базы данных » Ошибка кодировки при работе с dbf-файлом
1
agryn
Импортирую данные из dbf-файла (1С7.7)
import dbf
ONEC_PATH = '/home/sash/1Cv7/'
table_spravochnik = dbf.Table(ONEC_PATH + 'SC12.DBF')
table_spravochnik.open('read-only')
spravochnik_line = table_spravochnik[0] ## первая запись из таблицы
spravochnik_lin.descr
При вызове spravochnik_line.descr ошибка кодировки
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/dbf-0.95.004-py2.7.egg/dbf.py", line 2116, in __getattr__
    value = self._retrieve_field_value(index, name)
  File "/usr/local/lib/python2.7/dist-packages/dbf-0.95.004-py2.7.egg/dbf.py", line 2312, in _retrieve_field_value
    datum = retrieve(record_data, fielddef, self._meta.memo, self._meta.decoder)
  File "/usr/local/lib/python2.7/dist-packages/dbf-0.95.004-py2.7.egg/dbf.py", line 3064, in retrieve_character
    return fielddef[CLASS](decoder(data)[0])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd2 in position 0: ordinal not in range(128)
, при вызове spravochnik_line.id данные беруться без проблем
Сам файл корректно отображается с кодировкой pt154 (в OpenOffice).
spravochnik_line.descr.decode('pt154') также не рулит.
В чем прикол?
P.S. Да забыл написать это пробую делать из под Ubuntu 12.04 (x86)
Rodegast
Я так DBF читал:
from dbfpy import dbf
db = dbf.Dbf("./1SACCS.DBF")
for rec in db:
	print rec.asDict()["SCHIM"].decode("cp1251")
sypper-pit
from dbfread import DBF
for record in DBF('FOXUSER.DBF'):
     print(record)
Выдаёт данные в виде
OrderedDict([(u'TYPE', u'PREFW'), (u'ID', u'WINDCMD'), (u'NAME', u'DEFAULT'), (u'READONLY', False), (u'CKVAL', 64286), (u'DATA', u'\x04\x00\x03\x00\x00\x00\u044f\u044f\x04\x00(\x04\x00\x00\x10\x00\x00\x00\u0448\x04\x00\x00\u201a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u2021\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Courier New\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\u041c\x01\x00\x00\x00'), (u'UPDATED', datetime.date(2012, 8, 29))])
весь момент именно с кодировкой
sypper-pit
только надо поставить http://dbfread.readthedocs.org/en/latest/
Shaman
Там есть параметр
tbl = dbf.Table(os.path.join(dir_name, 'TABLE.DBF'), codepage='cp866')
Или глобально
dbf.default_codepage = 'cp866'
Shaman
Rodegast
Я так DBF читал:
Пользовался этой библиотекой, т.к. позволяет читать dbf из потока, но она не умеет кодировки. Пришлось научить.
--- D:\temp\dbfpy\header.py
+++ C:\projects\oms\dbfpy\header.py
@@ -51,12 +51,12 @@
"""

__slots__ = ("signature", "fields", "lastUpdate", "recordLength",
- "recordCount", "headerLength", "changed", "_ignore_errors")
+ "recordCount", "headerLength", "changed", "_ignore_errors", "languageDriver")

## instance construction and initialization methods

def __init__(self, fields=None, headerLength=0, recordLength=0,
- recordCount=0, signature=0x03, lastUpdate=None, ignoreErrors=False,
+ recordCount=0, signature=0x03, lastUpdate=None, ignoreErrors=False, languageDriver=0x01
):
"""Initialize instance.

@@ -92,6 +92,7 @@
self.headerLength = headerLength
self.recordCount = recordCount
self.ignoreErrors = ignoreErrors
+ self.languageDriver = languageDriver
# XXX: I'm not sure this is safe to
# initialize `self.changed` in this way
self.changed = bool(self.fields)
@@ -118,7 +119,7 @@
_year += 1900
## create header object
_obj = cls(None, _hdrLen, _recLen, _cnt, ord(_data[0]),
- (_year, ord(_data[2]), ord(_data[3])))
+ (_year, ord(_data[2]), ord(_data[3])), languageDriver=ord(_data[29]))
## append field definitions
# position 0 is for the deletion flag
_pos = 1
Далее работа велась так (предполагалось, дадут незнамо как оформленный dbf, но 100% с кириллицей):
ENCODING = {38: 'cp866', 101: 'cp866', 150: 'mac_cyrillic', 201: 'cp1251'}
 
class Record(object):
    def __init__(self, r):
        self.encoding = ENCODING.get(r.dbf.header.languageDriver, 'cp866')
        self.record = r
 
    def __getattr__(self, item):
        v = self.record[item]
        if isinstance(v, (str, unicode)):
            return v.strip().decode(self.encoding)
        return v
 
def read_table(arc, name):
 
    def arc2mem(arc, name, mem):
        with arc.open(name) as stream:
            while True:
                d = stream.read(4096)
                if not d:
                    break
                mem.write(d)
 
    with BytesIO() as memf:
        arc2mem(arc, name, memf)
        tbl = dbf.Dbf(memf, readOnly=True)
        for r in tbl:
            yield Record(r)
        tbl.close()
Jony1990
У меня проблема в том же месте ! как там отредактировать не весь код. а его начало ?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB