Saltar al contenido

¿Existe un módulo de Python 3 para leer archivos .dbf escritos por ArcGIS for Desktop?

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)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *