Search code examples
pythonpython-3.xfoxprodbf

How to read and create new FoxPro 2.6 database table using Python dbf library


library version: dbf 0.97.0, python version 3.5.5

I am trying to create a new FoxPro 2.6 .DBF file with the dbf library. I run

    >>> import dbf
    >>> table = dbf.Table('test', 'TEST C(40); TEST2 N(3,0); TEST3 C(3)', dbf_type='fp')

    >>> table.open(mode=dbf.READ_WRITE)
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "...\Miniconda3\envs\myenv\lib\site-packages\dbf\__init__.py", line 5793, in open
        raise DbfError("Unsupported dbf type: %s [%x]" % (version_map.get(header.version, 'Unknown: %s' % header.version), header.version))
    dbf.DbfError: Unsupported dbf type: Unknown: 0 [0]

when I run the open for the second time it seems OK:

    >>> table.open(mode=dbf.READ_WRITE)
    dbf.Table('test.dbf', status=<DbfStatus.READ_WRITE: 2>)

however when I try to write some data to the table it gets stuck:

    >>> table.append(("Lorem ipsum", 123, "321"))
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "...\Miniconda3\envs\myenv\lib\site-packages\dbf\__init__.py", line 5516, in append
        newrecord = Record(recnum=header.record_count, layout=meta, kamikaze=kamikaze)
      File "...\Miniconda3\envs\myenv\lib\site-packages\dbf\__init__.py", line 2773, in __new__
        record._update_disk()
      File "...\Miniconda3\envs\myenv\lib\site-packages\dbf\__init__.py", line 3100, in _update_disk
        layout.dfd.seek(location)
    ValueError: seek of closed file

If I add a memo field to the table it opens (I don't have to call it twice) and appends correctly.

Is this a bug or am I just doing something wrong?


Solution

  • Quick answer: Upgrade to 0.97.2.


    Long answer: There was a bug in the header creation of 'fp' tables with no memos, which has now been fixed.

    Note: dbf.Table returns the table CLOSED; however, some commands will automatically open and close the table for you:

    • the with statement
    • dbf.Processing()
    • dbf.add_fields()
    • dbf.delete_fields()
    • dbf.rename_field()