Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 16, 2013 22:39:38

agryn
От: Ровно (Украина)
Зарегистрирован: 2011-12-14
Сообщения: 189
Репутация: +  0  -
Профиль   Отправить e-mail  

Ошибка кодировки при работе с dbf-файлом

Импортирую данные из 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)

Офлайн

#2 Ноя. 19, 2013 17:14:19

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2555
Репутация: +  178  -
Профиль   Отправить e-mail  

Ошибка кодировки при работе с dbf-файлом

Я так DBF читал:

from dbfpy import dbf
db = dbf.Dbf("./1SACCS.DBF")
for rec in db:
	print rec.asDict()["SCHIM"].decode("cp1251")



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#3 Фев. 17, 2016 05:50:13

sypper-pit
От: Ulan-Ude(msk)
Зарегистрирован: 2009-01-30
Сообщения: 1102
Репутация: +  6  -
Профиль   Отправить e-mail  

Ошибка кодировки при работе с dbf-файлом

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))])
весь момент именно с кодировкой

Офлайн

#4 Фев. 17, 2016 05:52:57

sypper-pit
От: Ulan-Ude(msk)
Зарегистрирован: 2009-01-30
Сообщения: 1102
Репутация: +  6  -
Профиль   Отправить e-mail  

Ошибка кодировки при работе с dbf-файлом

только надо поставить http://dbfread.readthedocs.org/en/latest/

Офлайн

#5 Фев. 17, 2016 08:58:31

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Ошибка кодировки при работе с dbf-файлом

Там есть параметр

tbl = dbf.Table(os.path.join(dir_name, 'TABLE.DBF'), codepage='cp866')
Или глобально
dbf.default_codepage = 'cp866'

Офлайн

#6 Фев. 17, 2016 12:03:39

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Ошибка кодировки при работе с dbf-файлом

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()

Офлайн

#7 Апрель 24, 2020 22:51:39

Jony1990
Зарегистрирован: 2020-04-24
Сообщения: 12
Репутация: +  -1  -
Профиль   Отправить e-mail  

Ошибка кодировки при работе с dbf-файлом

У меня проблема в том же месте ! как там отредактировать не весь код. а его начало ?

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version