Форум сайта python.su
Импортирую данные из 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
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)
Офлайн
Я так DBF читал:
from dbfpy import dbf db = dbf.Dbf("./1SACCS.DBF") for rec in db: print rec.asDict()["SCHIM"].decode("cp1251")
Офлайн
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))])
Офлайн
только надо поставить http://dbfread.readthedocs.org/en/latest/
Офлайн
Там есть параметр
tbl = dbf.Table(os.path.join(dir_name, 'TABLE.DBF'), codepage='cp866')
dbf.default_codepage = 'cp866'
Офлайн
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
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()
Офлайн
У меня проблема в том же месте ! как там отредактировать не весь код. а его начало ?
Офлайн