Skip to main content

A Python library to manipulate DBase III database files

Project description

DBase III Python Library

Python library meant to manipulate DBase III database files. It allows reading, writing, adding, and updating records in the database.

Even though this file format for databases is largely no longer in use, the present work is a minitool useful to retrieve legacy data, as much as a tribute to a beautiful part of computer history.

Features

  • Read DBase III database files
  • Write to DBase III database files
  • Add new records
  • Update existing records
  • Filter and search records

Installation

To install the library, clone this repository and navigate to the project directory:

git clone https://github.com/sandy98/dbase3-py.git
cd dbase3-py

or

pip install dbase3-py

Usage

Main class

from dbase3_py.dbase3 import DBaseFile, FieldType
test = DbaseFile.create('db/test.dbf',
                    [('name', FieldType.CHARACTER.value, 50, 0),
                        ('age', FieldType.NUMERIC.value, 3, 0)])
test.add_record('John Doe', 30)
test.add_record('Jane Doe', 25)

print(test)
print(len(test))
print(test[:])
print(test.filter('name', 'ja', comp_func=self.istartswith))

Database browser utility

python3 dbfview.py <dbf_file>

or, even better, if dbase3_py is installed using pip, it will install dbfview as a script, thus:

dbfview <dbf_file>

A convenient CLI cursed based utility to browse .dbf files.

Module level usage

By issuing the command:

python3 -m dbase3_py

the module itself is invoked (more specifically, main.py), resulting in a traversal of the file system lookinf for .dbf files. At the end, should the search be successful, the user is offered with a numbered menu of existing dbf files, ready to be read by dbfview.

Comments

The module itself, DBaseFile class and all its methods are thoroughly documented, so it should be easy to follow up.

Esentially, each instance of DBaseFile, be it instanced through an existing DBase III file, or created through the factory method DBaseFile.create(filename), is a list like object with indexing capabilities, which also acts as an iterator through the records present in the .dbf file. It also supports the 'len' method, reporting the number of records present in the database, even those marked for deletion. On top of that, there is a group of methods meant for data manipulation (add_record for inserts, update_record for updates and del_record for marking/unmarking deletions). There is also a group of methods (search, index, find, filter) to aid in retrieving selected data.

At it present stage of development, there is not support for memo fields or index fields, though this is planned for future releases, should enough interest arise. It's also planned an exec method to execute SQL-like statements. not functional right now.

For further information see the documentation below.

Documentation

Classes

DBaseFile

Class to manipulate DBase III database files.

Dunder and 'private' Methods

  • __init__(self, filename: str): Initializes an instance of DBase3File from an existing dbf file.
  • __del__(self): Closes the database file when the instance is destroyed.
  • __len__(self): Returns the number of records in the database, including records marked to be deleted. Allows writing: len(dbasefileobj)
  • __getitem__(self, key): Returns a single record or a list of records (if slice notation is used) from the database. Allows: dbasefileobj[3] or dbasefileobj[3:7]
  • __iter__(self): Returns an iterator over the records in the database. Allows for record in dbasefileobj: ...
  • __str__(self): Returns a string representation of the database.
  • _init(self): Initializes the database structure by reading the header and fields. Meant for private use by DBaseFile instances.
  • def _test_key(self, key): Tests if the key is within the valid range of record indexes. Raises an IndexError if the key is out of range. Meant for internal use only.

Class Methods

  • create(cls, filename: str, fields: List[Tuple[str, FieldType, int, int]]): Creates a new DBase III database file with the specified fields. Returns a DbaseFile object pointing to newly created dbase file.

Data Manipulation methods

  • add_record(self, record_data: dict): Adds a new record to the database.
  • update_record(self, index: int, record_data: dict): Updates an existing record in the database.
  • save_record(self, key, record): Writes a record (dictionary with field names and field values) to the database at the specified index. Params: key is the index (0 based position in dbf file). record is a dictionary corresponding to an item in the database (i.e: {'id': 1, 'name': "Jane Doe"}) Used internally by update_record
  • del_record(self, key, value = True): Marks for deletion the record identified by the index 'key', or unmarks it if value == False. To efectively erase the record from disk the deletion must be confirmed by using dbasefileobj.write()
  • write(self, filename=None): Writes the current file to disk, skipping records marked for deletion. If a filename is provided, other the current filename, saves the database file to the new destination, keeping previous filename as is.

Data searching/filtering methods

  • search(self, fieldname, value, start=0, funcname="", comp_func=None): Searches for a record with the specified value in the specified field, starting from the specified index, for which the specified comparison function returns True. Returns a tuple with index:int and record:dict
  • find(self, fieldname, value, start=0, comp_func=None): Wrapper for search() with funcname="find". Returns the first record (dictionary) found, or None if no record meeting given criteria is found.
  • index(self, fieldname, value, start=0, comp_func=None): Wrapper for search() with funcname="index". Returns index of the first record found, or -1 if no record meeting given criteria is found.
  • filter(self, fieldname, value, comp_func=None): Returns a list of records (dictionaries) that meet the specified criteria.
  • exec(self, sql_cmd:str): Meant for retrieving data in a custom manner. Not operational yet. Invoking it raises a NotImplemented error.

Data listing methods

  • list(self, start=0, stop=None, fieldsep="|", recordsep='\n', records:list=None): Returns a list of records from the database, starting at 'start', ending at 'stop' or EOF, having fields separated by 'fieldsep' and records separated by '\n'. If 'records' is not None, the provided list is used instead of retrieving values from the database.
  • csv(self, start=0, stop=None, records:list = None): Wrapper for 'list', using ',' as fieldsep.
  • table(self, start=0, stop=None, records:list = None): Retrieves selected records using ad-hoc format, same as provided by sqlite3 CLI in .table mode.

Static Methods (Auxiliary functions for searching/filtering)

  • istartswith(f: str, v: str) -> bool: Checks if the string f starts with the string v, ignoring case.
  • iendswith(f: str, v: str) -> bool: Checks if the string f ends with the string v, ignoring case.

Properties

  • 'fields': Retrieves the list of fields from which the database records are assembled. Each field object in the list has a name, type (as per FieldType Enum) and length.

  • 'field_names': Retrieves a list with the name of each field in the database.

  • 'field_types': Retrieves a list with the type of each field in the database.

  • 'field_lengths': Retrieves a list with the length of each field in the database.

  • 'max_field_lengths': Returns the maximum length of the specified field (including length of field name) in the database. Useful for retrieving lines with adjusted width for each field. Internally uses def max_field_length(self, field)

  • 'tmax_field_lengths': Same as max_field_lengths, threaded version, in an unsuccessful attemp of accelerating the process. Anyway, it works.

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Contact

For any questions or suggestions, please contact Domingo E. Savoretti.


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

dbase3_py-1.7.1.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

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

dbase3_py-1.7.1-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

File details

Details for the file dbase3_py-1.7.1.tar.gz.

File metadata

  • Download URL: dbase3_py-1.7.1.tar.gz
  • Upload date:
  • Size: 21.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.11.0rc1

File hashes

Hashes for dbase3_py-1.7.1.tar.gz
Algorithm Hash digest
SHA256 f91e9995b6efc1415c1509f362878c3833c3ea00fe83d3c024adaf69e97eaf07
MD5 39ac9315c91d99547e0d3c0d5e43c39f
BLAKE2b-256 7ea7dca61bda7bd0941a1c467dd2baf5c98b7093fc1ee597b1a7afc2c429a431

See more details on using hashes here.

File details

Details for the file dbase3_py-1.7.1-py3-none-any.whl.

File metadata

  • Download URL: dbase3_py-1.7.1-py3-none-any.whl
  • Upload date:
  • Size: 14.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.11.0rc1

File hashes

Hashes for dbase3_py-1.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b293158fab92393997ec274c22bb841eb4f77c31d36a6e8850190d6e5e58cc4c
MD5 1cdb3d39e226d0527e6f0aac1dce299a
BLAKE2b-256 13aebf32db22b9d154f1d339c34ce579a9ea5c1fd964d4e8617d48ddb331a16a

See more details on using hashes here.

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