Python Write value in dbf file

10,224

The dbf module appears to have changed. Here's 'my new and improved' answer. The original answer appears below.

New answer (2018 11 28)

  • I create a table with just three fields then open it in read-write mode in order to add three records to it. I print the records to demonstrate success.
  • I close the table and re-open it in read-write mode, to add a field for telephone number then proceed to modify each record with a telephone number. Again, I print the records to demonstrate success.
  • I previously found that the with record as r construction makes it possible to access individual fields of a record. This time I was reminded that string fields are stored with blank fill on the right. That's why I used strip() in r.name.strip(), so that I could do a lookup in the dictionary.

--

## code to work with dbf module  aenum-2.1.2 dbf-0.97.11

import dbf

table = dbf.Table('temptable', 'name C(30); age N(3,0); birth D')

print('db definition created with field names:', table.field_names)

table.open(mode=dbf.READ_WRITE)
for datum in (('John Doe', 31, dbf.Date(1979, 9,13)),('Ethan Furman', 102, dbf.Date(1909, 4, 1)),('Jane Smith', 57, dbf.Date(1954, 7, 2)),('John Adams', 44, dbf.Date(1967, 1, 9)),):
    table.append(datum)

print ('records added:')
for record in table:
    print (record)
    print ('-----')

table.close()

table.open(mode=dbf.READ_WRITE)

table.add_fields('telephone C(10)')

telephones = {'John Doe': '1234', 'Ethan Furman': '2345', 'Jane Smith': '3456', 'John Adams': '4567'}
for record in table:
    with record as r:
        r.telephone = telephones[r.name.strip()]

print ('updated records')
for record in table:
    print (record)
    print ('-----')

Original answer

You can add a column to a dbf table and then write values to individual cells in that table in the way demonstrated in this script. Notice that I've add the same telephone number to all of the cells.

I begin by creating the table and contents offered in the documentation for this product. I verify that field_names and the contents of the table are what would be expected.

>>> import dbf
>>> table = dbf.Table('temptable', 'name C(30); age N(3,0); birth D')
>>> table.field_names
['name', 'age', 'birth']
>>> table.open()
dbf.ver_33.Table('temptable.dbf', status=<DbfStatus.READ_WRITE: 2>)
>>> for datum in (('John Doe', 31, dbf.Date(1979, 9,13)),('Ethan Furman', 102, dbf.Date(1909, 4, 1)),('Jane Smith', 57, dbf.Date(1954, 7, 2)),('John Adams', 44, dbf.Date(1967, 1, 9)),):
...     table.append(datum)
... 
>>> for record in table:
...     record
...     
 John Doe                       3119790913
 Ethan Furman                  10219090401
 Jane Smith                     5719540702
 John Adams                     4419670109
>>> table.close()

Then I re-open the table, add a column for telephone numbers and verify the newly updated field_names attribute. The new field is blank, as expected.

>>> table = dbf.Table('temptable.dbf')
>>> table.open()
dbf.ver_33.Table('temptable.dbf', status=<DbfStatus.READ_WRITE: 2>)
>>> table.add_fields('Telephone C(10)')
>>> table.field_names
['name', 'age', 'birth', 'telephone']
>>> for record in table:
...     record.name, record.birth, record.telephone
...     
('John Doe                      ', datetime.date(1979, 9, 13), '          ')
('Ethan Furman                  ', datetime.date(1909, 4, 1), '          ')
('Jane Smith                    ', datetime.date(1954, 7, 2), '          ')
('John Adams                    ', datetime.date(1967, 1, 9), '          ')

I made several attempts to set individual values of telephone without success. One of the diagnostic messages pointed me toward using a syntactic construction involving with and this one works. (Incidentally, the field length I chose for North American telephone numbers was too small.)

>>> for record in table:
...     with record as r:
...         r.telephone = 'xxx xxx xx'
...         
>>> for record in table:
...     record
...     
 John Doe                       3119790913xxx xxx xx
 Ethan Furman                  10219090401xxx xxx xx
 Jane Smith                     5719540702xxx xxx xx
 John Adams                     4419670109xxx xxx xx
>>> table.close()
Share:
10,224
Ken White
Author by

Ken White

I've been programming since the early days of dBASE III+, working in dBASE, FoxPro, Clipper, C, C++, x86 assembler, and Delphi (since version 1 was released). I also have experience with (but am in no way an expert on) SQL Server, Oracle, Interbase, and Advantage Database Server SQL database engines. I've also dabbled in various other languages and technologies such as Java development for Android, Basic4Android, Delphi Prism, C#, and others. I've also worked in various scopes, from an independent consultant and contract programmer to being employed by a Fortune 10 company and government agencies (State and Federal). I'm a veteran of the US Air Force, serving both in flight line operations and administrative positions for five years in locations across the US. I co-authored a Delphi/C++Builder function and component library (Clipper Functions for Delphi, or CFD), initially starting off as a function library to ease the transition from Clipper (a DOS programming language) to Delphi (an OOP Pascal Windows language). At one point CFD had more than 5,000 registered users, and maintained a 100% upgrade rate for the final three versions released. We had customers on every continent except the Antarctic. I still have users today that contact me for updated versions for new Delphi releases (as recently as late 2012), even though the last official release was in 2000. Software and libraries I've written have been used by top corporations (including some of the major telecommunications companies). I also wrote (under contract to a corporation based in Dallas, TX) one of the early QuickBooks API applications sold on the Intuit website in 2001. I currently work with medical claims adjudication software, Ansi X12 EDI, insurance billing, and other health care related software, as well as network administration (Novell Netware and Windows 2003/2008), and document storage.

Updated on June 11, 2022

Comments

  • Ken White
    Ken White almost 2 years

    I am using this DBF library http://pythonhosted.org/dbf/

    I added a column to DBF table, now I need to add values in this column, but I am having problems.

    import dbf
    import random
    
    db = dbf.Table('test.dbf')
    with db:
        #db.add_fields('ClasseType C(10)')
        for record in db:
            dbf.write(record, data="test")
    

    Error:

    "Traceback (most recent call last):
      File "C:/Python/23/dbf/addField.py", line 9, in 
        dbf.write(record, data="test")
      File "C:\Anaconda2\lib\site-packages\dbf\ver_2.py", line 7990, in write
        gather(record, kwargs)
      File "C:\Anaconda2\lib\site-packages\dbf\ver_2.py", line 8245, in gather
        raise FieldMissingError(key)
    dbf.ver_2.FieldMissingError: 'data:  no such field in table'
    
    Process finished with exit code 1
    
    • Ignacio Vazquez-Abrams
      Ignacio Vazquez-Abrams over 6 years
      Why do you think the error message is lying?
    • Bill Bell
      Bill Bell over 6 years
      If an answer meets your requirements you should, please, mark it 'accepted'.
  • Ethan Furman
    Ethan Furman over 6 years
    Nice answer! +1 :)
  • Bill Bell
    Bill Bell over 6 years
    @EthanFurman I didn't make the connection until I glanced up a moment ago and saw your name.
  • Vincent Wen
    Vincent Wen over 5 years
    I believe this answer doesn't work anymore for latest dbf package, you should use table.open(mode=dbf.READ_WRITE) to make table writable, otherwise you'll get error
  • Bill Bell
    Bill Bell over 5 years
    @VincentWen: Thank you! Please see new answer. I believe it's correct now.