A Python package for reading and writing DBF files, powered by a Rust core
Project description
fastdbf
fastdbf is a high-performance Python package for reading and writing .dbf files.
Written in Rust (using PyO3), it provides standard Python bindings designed specifically for large datasets, where traditional pure-Python solutions (like the standard dbf package) suffer from significant performance bottlenecks.
Status
fastdbf is fully production-ready for core data exchange workloads.
Supported Features
- High-Performance I/O: Lightning fast reads and writes of standard
.dbffiles. - Zero-Copy Bulk Transfers: Native Apache Arrow integration (
to_arrow(),extend_arrow()) for high-speed exchange with Pandas/Polars. - Visual FoxPro Support: Direct handling of VFP
.dbfflavors, including mandatory null-flag layouts. - Memo Fields: Automatic management of companion
.fptmemo files for unbounded strings. - Native Type Mapping: Correct Python/Arrow types for dates, datetimes, and integers — no manual casting needed.
- Strict Typing: Clear data mappings with custom exception classes (
DbfFormatError).
Not Implemented yet
- In-place Schema Modification: Dynamic addition/removal of columns on pre-written tables (currently raises
UnsupportedDbfTypeError). - Advanced Engine Tools: Indexing, cross-table relationships, or built-in query paradigms.
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
from datetime import date, datetime
specs = "name C(25) null; age N(3,0) null; birth D null; created T null; active L null"
with fastdbf.Table("people.dbf", specs, dbf_type="vfp") as table:
table.append({
"name": "Alice", # case-insensitive keys
"age": 30,
"birth": date(1994, 5, 20),
"created": datetime(2024, 1, 1, 12, 0),
"active": True,
})
table.append({
"NAME": None,
"AGE": None,
"BIRTH": None,
"CREATED": None,
"ACTIVE": None,
})
Type Mapping
fastdbf maps DBF field types to native Python and Arrow types, so no manual casting is needed in either direction.
DBF → Python / Arrow
| DBF Field | DBF Type Code | Python type | Arrow type |
|---|---|---|---|
| Character | C |
str |
Utf8 |
| Numeric (integer) | N(n,0) |
int |
Int64 |
| Numeric (decimal) | N(n,k) |
float |
Float64 |
| Date | D |
datetime.date |
Date32 |
| DateTime | T |
datetime.datetime |
Timestamp(ms) |
| Logical | L |
bool |
Boolean |
| Integer | I |
int |
Int32 |
| Double | B |
float |
Float64 |
Python / Pandas → DBF (writing)
append() and extend_arrow() both accept the types listed above, plus Pandas-native types without any manual casting:
| Input type | DBF field written |
|---|---|
datetime.date |
D (Date) |
datetime.datetime |
T (DateTime) |
pandas.Timestamp |
T (DateTime) |
numpy.int64 / int |
N(n,0) or I |
numpy.float64 / float |
N(n,k) or B |
Note:
append(dict)is case-insensitive —"name","NAME", and"Name"all resolve to the same DBF field.
Field Types
Currently supported field types:
CCharacterDDateLLogicalNNumericFFloatIIntegerBDoubleT/@DateTimeYCurrencyM/G/Pas 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 / Arrow Integration
Reading a DBF into Pandas (recommended)
Using the Arrow interface gives correct types directly — no extra dtype conversion needed:
import fastdbf
import pyarrow as pa
with fastdbf.Table("data.dbf").open("r") as table:
df = pa.record_batch(table.to_arrow()).to_pandas()
# Result:
# - Date fields → datetime64 (via object column of datetime.date)
# - DateTime fields → datetime64[ms]
# - Numeric(N,0) → Int64 (no silent float coercion!)
# - Logical → bool
Writing a Pandas DataFrame to DBF
Method A: Arrow (fastest, recommended for large DataFrames)
import fastdbf
import pyarrow as pa
batch = pa.RecordBatch.from_pandas(df)
with fastdbf.Table("output.dbf", field_specs="NAME C(20); AGE N(10,0); BIRTH D; CREATED T") as table:
table.extend_arrow(batch)
Method B: Row-by-row append (no dependencies beyond fastdbf)
import fastdbf
with fastdbf.Table("output.dbf", field_specs="NAME C(20); AGE N(10,0); BIRTH D; CREATED T") as table:
for _, row in df.iterrows():
table.append(row.to_dict()) # pandas.Timestamp, numpy types accepted natively
The _deleted column
All read methods expose a _deleted: bool column. This reflects the DBF soft-delete flag — a standard DBF concept where records are logically marked as deleted (with a * marker byte) but remain physically in the file until a PACK operation removes them.
# Skip deleted records when reading:
df = df[~df["_deleted"]]
# Mark a record as deleted:
with table.record(0) as rec:
rec.set_deleted(True)
# Physically remove all deleted records:
table.pack()
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.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
# Drop internal meta-columns like '_deleted' if present
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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastdbf-0.5.2.tar.gz.
File metadata
- Download URL: fastdbf-0.5.2.tar.gz
- Upload date:
- Size: 286.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c42666782d792a5a6dbfde2fe27420b94e776c8d4fe513756fb3c5fd324b042b
|
|
| MD5 |
1237128601e014f55709e8052b57635e
|
|
| BLAKE2b-256 |
e6dc9eabef8738c8f692054091fd97098a92dce749567327e3b04c9678b7f1fa
|
Provenance
The following attestation bundles were made for fastdbf-0.5.2.tar.gz:
Publisher:
release.yml on Jonas-Bruns/fastdbf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastdbf-0.5.2.tar.gz -
Subject digest:
c42666782d792a5a6dbfde2fe27420b94e776c8d4fe513756fb3c5fd324b042b - Sigstore transparency entry: 1436017674
- Sigstore integration time:
-
Permalink:
Jonas-Bruns/fastdbf@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/Jonas-Bruns
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fastdbf-0.5.2-cp311-abi3-win_amd64.whl.
File metadata
- Download URL: fastdbf-0.5.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72458d490dacf375619da3a7f13d53ea468a8659b9dbb0118005337d4032f7f5
|
|
| MD5 |
80e91e4d772c614b4303da13ab4c94c6
|
|
| BLAKE2b-256 |
7760c940268315a4cfe03d858f01c16a82ada8cd8ef0bba759a51516865c3a76
|
Provenance
The following attestation bundles were made for fastdbf-0.5.2-cp311-abi3-win_amd64.whl:
Publisher:
release.yml on Jonas-Bruns/fastdbf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastdbf-0.5.2-cp311-abi3-win_amd64.whl -
Subject digest:
72458d490dacf375619da3a7f13d53ea468a8659b9dbb0118005337d4032f7f5 - Sigstore transparency entry: 1436017698
- Sigstore integration time:
-
Permalink:
Jonas-Bruns/fastdbf@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/Jonas-Bruns
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fastdbf-0.5.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: fastdbf-0.5.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.5 MB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed50d67cb1eb1dc1b3da5e2cbbadf2d3575f28ce9a3cfa3011e12aec128e4876
|
|
| MD5 |
75465140969a204550f3ff082baf7726
|
|
| BLAKE2b-256 |
11508513b71df56a4e49eb802de78f6a342bcc49f52e6f0e2605329324025346
|
Provenance
The following attestation bundles were made for fastdbf-0.5.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on Jonas-Bruns/fastdbf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastdbf-0.5.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
ed50d67cb1eb1dc1b3da5e2cbbadf2d3575f28ce9a3cfa3011e12aec128e4876 - Sigstore transparency entry: 1436017753
- Sigstore integration time:
-
Permalink:
Jonas-Bruns/fastdbf@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/Jonas-Bruns
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fastdbf-0.5.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: fastdbf-0.5.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efea2ace9c4c2aa48c47950c6081258e9d592bab6340e83a5a5ea4aa3cac2a5b
|
|
| MD5 |
938bdf9bdbce6c8a714a4877eec8ffdd
|
|
| BLAKE2b-256 |
a66ddc688b16943baf040ad6c4d9cc191f35c077c7ed6f309a650ea10450dd20
|
Provenance
The following attestation bundles were made for fastdbf-0.5.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on Jonas-Bruns/fastdbf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastdbf-0.5.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
efea2ace9c4c2aa48c47950c6081258e9d592bab6340e83a5a5ea4aa3cac2a5b - Sigstore transparency entry: 1436017742
- Sigstore integration time:
-
Permalink:
Jonas-Bruns/fastdbf@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/Jonas-Bruns
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fastdbf-0.5.2-cp311-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: fastdbf-0.5.2-cp311-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.11+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f31d7fc00f9b8da76c11ba70c39780a4b0f983f67f9e3211cd5cc3daf663a6a1
|
|
| MD5 |
c8f4ace7f99499dc4d39942bc1c3466f
|
|
| BLAKE2b-256 |
e8486cb6fda428e32da37b2cceb3ffcfce552f7942cac518381e8093685f186b
|
Provenance
The following attestation bundles were made for fastdbf-0.5.2-cp311-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on Jonas-Bruns/fastdbf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastdbf-0.5.2-cp311-abi3-macosx_11_0_arm64.whl -
Subject digest:
f31d7fc00f9b8da76c11ba70c39780a4b0f983f67f9e3211cd5cc3daf663a6a1 - Sigstore transparency entry: 1436017718
- Sigstore integration time:
-
Permalink:
Jonas-Bruns/fastdbf@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/Jonas-Bruns
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fastdbf-0.5.2-cp311-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: fastdbf-0.5.2-cp311-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.4 MB
- Tags: CPython 3.11+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1766d901488c40fb04e33540951fc1eb047153d191d15ad5d23e2dbe971dbd62
|
|
| MD5 |
653921cbc134b675f18347e3280a5238
|
|
| BLAKE2b-256 |
a3fe8c4dd4afd3e2dd25cd61420afe63959e2a9288abfe924fac62bfd12d2154
|
Provenance
The following attestation bundles were made for fastdbf-0.5.2-cp311-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on Jonas-Bruns/fastdbf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastdbf-0.5.2-cp311-abi3-macosx_10_12_x86_64.whl -
Subject digest:
1766d901488c40fb04e33540951fc1eb047153d191d15ad5d23e2dbe971dbd62 - Sigstore transparency entry: 1436017766
- Sigstore integration time:
-
Permalink:
Jonas-Bruns/fastdbf@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/Jonas-Bruns
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee56c58f7647356d88ebaa8b967cb9c9f3e130b3 -
Trigger Event:
push
-
Statement type: