Skip to main content

A Python package for reading and writing DBF files, powered by a Rust core

Project description

fastdbf

fastdbf is a Rust-based reimplementation of the core ideas from ethanfurman/dbf, exposed as a Python package through PyO3.

The current focus is a practical Python-first package for reading and writing .dbf files, including Visual FoxPro-style nullable fields.

Performance Benchmark

Status

This project is in an early but usable state.

Implemented today:

  • read .dbf files from Python
  • inspect field metadata and field types
  • create new tables from DBF-style field specifications
  • append rows from dictionaries or tuples
  • write tables back to disk
  • Visual FoxPro null-flag support for nullable fields
  • a Rust core with test coverage for read/write roundtrips

Not implemented yet:

  • full memo file support (.dbt / .fpt)
  • full original dbf compatibility surface
  • record objects with attribute access like record.name
  • indexing, relations, PQL, and most advanced helpers from the original project

Installation

Create or sync the development environment with uv:

uv sync

Install into the current environment with uv:

uv pip install .

Editable install:

uv pip install -e .

Run tests:

uv run pytest

Build a wheel:

uv build

Quick Start

Read an existing DBF file:

import fastdbf

with fastdbf.Table("people.dbf").open("r") as table:
    print(table.kind)
    print(table.field_names)
    print(table.record_count)
    print(table.row(0))

    for field in table.fields():
        print(field["name"], field["type_code"], field["nullable"])

    for row in table:
        print(row)

Create and write a new DBF file:

import fastdbf

specs = "name C(25) null; age N(3,0) null; birth D null; active L null"
with fastdbf.Table("people.dbf", specs, dbf_type="vfp") as table:
    table.append({
        "NAME": "Spunky",
        "AGE": 23,
        "BIRTH": "1989-07-23",
        "ACTIVE": True,
    })

    table.append({
        "NAME": None,
        "AGE": None,
        "BIRTH": None,
        "ACTIVE": None,
    })

Field Types

Currently supported field types:

  • C Character
  • D Date
  • L Logical
  • N Numeric
  • F Float
  • I Integer
  • B Double
  • T / @ DateTime
  • Y Currency
  • M / G / P as reference values

Nullable fields are supported through null or nullable modifiers in the field specification:

"name C(25) null; amount N(10,2) nullable; created T null"

Nullable fields should be used with dbf_type="vfp" for Visual FoxPro-compatible null flags.

pandas Example

import pandas as pd
import fastdbf

with fastdbf.Table("input.dbf").open("r") as table:
    df = pd.DataFrame(list(table))
    df["NAME"] = df["NAME"].str.upper()

    field_specs = []
    for field in table.fields():
        code = field["type_code"]
        nullable = " null" if field["nullable"] else ""
        if code == "C":
            field_specs.append(f'{field["name"]} C({field["length"]}){nullable}')
        elif code in ("N", "F"):
            field_specs.append(
                f'{field["name"]} {code}({field["length"]},{field["decimals"]}){nullable}'
            )
        else:
            field_specs.append(f'{field["name"]} {code}{nullable}')

dbf_type = "vfp" if any(f["nullable"] for f in table.fields()) else "db3"
specs = "; ".join(field_specs)

with fastdbf.Table("output.dbf", specs, dbf_type=dbf_type) as out:
    for row in df.to_dict(orient="records"):
        out.append(row)

Performance & Columnar I/O (Arrow)

For maximum performance, especially with large datasets, fastdbf provides columnar read/write interfaces that avoid the high overhead of Python object allocation.

1. Apache Arrow Interface (Zero-Copy) — Fastest

Leverages the Arrow PyCapsule Interface to exchange data directly between Rust and Pandas / Polars / PyArrow without copying.

Read into Pandas via Arrow:

import fastdbf
import pyarrow as pa

with fastdbf.Table("data.dbf").open("r") as table:
    # Arrow Batch -> Pandas DataFrame
    df = pa.Table.from_batches([pa.record_batch(table.to_arrow())]).to_pandas()

Write from Pandas via Arrow:

import fastdbf
import pyarrow as pa

# Create Arrow batch from DataFrame
batch = pa.RecordBatch.from_pandas(df)

with fastdbf.Table("output.dbf", field_specs="NAME C(20); AGE N(10,2)") as table:
    table.extend_arrow(batch)

2. Columnar Interface (to_columns, extend_columns)

Reads/writes data as a dictionary of lists (one list per column). Faster than row-by-row processing but still bound by GIL limits.

Bulk Columnar Read:

import pandas as pd
import fastdbf

with fastdbf.Table("data.dbf").open("r") as table:
    cols = table.to_columns()
    df = pd.DataFrame(cols)

Bulk Columnar Write:

import pandas as pd
import fastdbf

# Assuming df ist das Pandas DataFrame
# Optionale interne Meta-Spalten wie '_deleted' entfernen
clean_data = {col: df[col].tolist() for col in df.columns if col != "_deleted"}

with fastdbf.Table("output.dbf", field_specs="NAME C(20); AGE N(10,2)") as table:
    table.extend_columns(clean_data)

Overview: Read/Write Methods compared

Method Implementation Pros
Row-by-Row table.row(), table.append() Easiest to use
Bulk Columnar to_columns(), extend_columns() No heavy dependencies
Zero-Copy Arrow to_arrow(), extend_arrow() Direct memory exchange

Documentation

Full Python API documentation:

Changelog:

Rust Example

use fastdbf::{Date, Table, Value};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut table = Table::new("name C(25); age N(3,0); birth D; qualified L")?;

    let mut record = table.new_record();
    record.insert(table.fields(), "name", Value::Character("Spunky".into()))?;
    record.insert(table.fields(), "age", Value::Numeric(23.0))?;
    record.insert(table.fields(), "birth", Value::Date(Some(Date::new(1989, 7, 23))))?;
    record.insert(table.fields(), "qualified", Value::Logical(Some(true)))?;
    table.push_record(record)?;

    table.write_to_path("example.dbf")?;
    Ok(())
}

License

This project is licensed under the Apache License 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastdbf-0.4.2.tar.gz (184.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fastdbf-0.4.2-cp311-abi3-win_amd64.whl (2.5 MB view details)

Uploaded CPython 3.11+Windows x86-64

fastdbf-0.4.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

fastdbf-0.4.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.2 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

fastdbf-0.4.2-cp311-abi3-macosx_11_0_arm64.whl (2.1 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

fastdbf-0.4.2-cp311-abi3-macosx_10_12_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file fastdbf-0.4.2.tar.gz.

File metadata

  • Download URL: fastdbf-0.4.2.tar.gz
  • Upload date:
  • Size: 184.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fastdbf-0.4.2.tar.gz
Algorithm Hash digest
SHA256 a29e927a529bc5b24c9c7701b3ffa777843bbc9ccf688e618ea78683e924e7b8
MD5 22768390fe1dd74a693acee83ddf2002
BLAKE2b-256 72742df46ff035be277cd50b28c8dc60613d86a676ac93a039d67ac340ff7aac

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastdbf-0.4.2.tar.gz:

Publisher: release.yml on Jonas-Bruns/fastdbf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastdbf-0.4.2-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: fastdbf-0.4.2-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fastdbf-0.4.2-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 3ca61d7dc1c5a97fe82b563e73407b5c4b306ce5f318d648185461e837ef0982
MD5 1e7412c2360dbf3bee1bd9d13a9dfef5
BLAKE2b-256 fc2ff8a8ee419fc0677d07c9d10f4b4041312e668f5017aeab4220cd502db855

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastdbf-0.4.2-cp311-abi3-win_amd64.whl:

Publisher: release.yml on Jonas-Bruns/fastdbf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastdbf-0.4.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fastdbf-0.4.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b5b6a6aca66991d16a6756f957015d35e714860610e93ee18b5a41bd451bc68a
MD5 7e6b146986f713a7c2db79292d3b020b
BLAKE2b-256 cc2303a9970f6c2114cc199ebb04fecf909c407f3fef18447f9957151dda1e63

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastdbf-0.4.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on Jonas-Bruns/fastdbf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastdbf-0.4.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fastdbf-0.4.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4ccd2ad066b443f3b442edf24f2868563a6955fe27a2bc1b2d2717acb677e2ef
MD5 0c6637855c7488eba6a8d7c1fbc5e0d0
BLAKE2b-256 e445f357cf03c0f3ae74cde98537214a5f364691fb999c0b875b80d1f161439c

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastdbf-0.4.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on Jonas-Bruns/fastdbf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastdbf-0.4.2-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fastdbf-0.4.2-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7d5022e64bf45153f9c84bd948bdc19d1115141df050b6ecaf9db00c5a851c08
MD5 2cad35be8ef95e0d53830ae53e4f555b
BLAKE2b-256 b978ff38ad2a70b5077615af4e043c86ccec34e611390654f02e0b22ddbbf744

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastdbf-0.4.2-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on Jonas-Bruns/fastdbf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastdbf-0.4.2-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for fastdbf-0.4.2-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 390caa0b7e9c982f43046cba2564d7d53fa6ec34c6f641a79579ba852ed37171
MD5 ec8927465106b917488e4b23a80b8f16
BLAKE2b-256 28b07b71bff290be3d425530fc80b6886ffff1ead806f6908e306c93be376533

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastdbf-0.4.2-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on Jonas-Bruns/fastdbf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page