user8359450
user8359450

Reputation:

Python Write value in dbf file

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

Upvotes: 2

Views: 14074

Answers (1)

Bill Bell
Bill Bell

Reputation: 21663

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()

Upvotes: 4

Related Questions