Solución:
Como todos los programadores de Python, lo haré
- primero vea el índice del paquete Python para archivos dbf (se especifica si no son compatibles con Python 3 o Python 2). dbfread, por ejemplo, funciona con Python 2.xy Python 3.x.
- Se pueden utilizar módulos geoespaciales como GDAL / OGR pero es necesario compilarlos (Linux, Mac OS X). Para los usuarios de Windows, Christoph Gohlke proporciona los binarios de Windows no oficiales para paquetes de extensión de Python con GDAL / OGR (Python 2.xy Python 3.x)
- y un módulo geoespacial puro de Python como Pyshp (Python 2.xo 3.x) también puede leer archivos dbf
- y finalmente, si conoce la estructura de un archivo dbf (Estructura del encabezado del archivo de datos para el archivo de tabla de la versión 7 de dBASE, por ejemplo), no es complicado programar un lector en Python puro con el módulo struct
Adapté esta función para python 2,7 a python 3, x, funciona para mí, pero sin garantía … 🙂
def dbfreader(f): #Found on http://code.activestate.com/recipes/362715-dbf-
reader-and-writer/ - by Raymond Hettinger
"""Returns an iterator over records in a Xbase DBF file.
The first row returned contains the field names.
The second row contains field specs: (type, size, decimal places).
Subsequent rows contain the data records.
If a record is marked as deleted, it is skipped.
File should be opened for binary reads.
Adapted for python 3,5 20-09-2017
"""
# See DBF format spec at:
# http://www.pgts.com.au/download/public/xbase.htm#DBF_STRUCT
numrec, lenheader = struct.unpack('<xxxxLH22x', f.read(32))
numfields = (lenheader - 33) // 32
fields = []
for fieldno in range(numfields): #PYTHON3
name, typ, size, deci = struct.unpack('<11sc4xBB14x', f.read(32))
name=name.decode('utf-8') #PYTHON3
typ=typ.decode('utf-8') #PYTHON3
name = name.replace(' ', '') # eliminate NULs from string
fields.append((name, typ, size, deci))
yield [field[0] for field in fields]
yield [tuple(field[1:]) for field in fields]
terminator = f.read(1)
terminator=terminator.decode('utf-8') #PYTHON3
assert terminator == 'r'
fields.insert(0, ('DeletionFlag', 'C', 1, 0))
fmt="".join(['%ds' % fieldinfo[2] for fieldinfo in fields])
fmtsiz = struct.calcsize(fmt)
for i in range(numrec):
recordb = struct.unpack(fmt, f.read(fmtsiz))
record=[]
for j in range(0,len(recordb)):
record.append(recordb[j].decode('utf-8')) #PYTHON3
if record[0] != ' ':
continue # deleted record
result = []
for (name, typ, size, deci), value in zip(fields, record):
if name == 'DeletionFlag':
continue
if typ == "N":
value = value.replace(' ', '').lstrip()
if (value == '') or "*" in value:
value = -99
elif deci:
value = decimal.Decimal(value)
else:
value = int(value)
elif typ == 'D':
y, m, d = int(value[:4]), int(value[4:6]), int(value[6:8])
value = datetime.date(y, m, d)
elif typ == 'L':
value = (value in 'YyTt' and 'T') or (value in 'NnFf' and 'F') or '?'
elif typ == 'F':
value = float(value)
result.append(value)
yield result
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)