I. Introduction:
There are some examples on the Internet of using dbfpy and dbfread libraries to operate dbf files. I compared some operation libraries and finally chose the dbf library because
The dbf library can complete addition, deletion, modification and query operations and is always updated, so use this library for encapsulation.
Visual operation software: I personally recommend DBFViewerPlus, which is faster and opens large files without lag.
2. Self-encapsulated dbf file operation library
Column definition
import dbf
class DbfHelper:
def __init__(self, path, field_specs=None):
"""
:param path:
:param field_specs: 'name C(30); age N(3,0); birth D'
field_specs 有内容时为新建(会覆盖已有文件),无内容时不会新建
"""
self.table = dbf.Table(path, field_specs)
self.table.open(mode=dbf.READ_WRITE)
def append_data(self, data):
"""
:param data: tuple or list : (('jjj',111,dbf.Date(2000,1,2),(),())
:return:
"""
for item in data: # item must be tuple, dict, record, cant be list
self.table.append(item)
def add_fields(self,field_specs):
"""
:param field_specs: 'name C(30); age N(3,0); birth D'
:return:
"""
self.table.add_fields(field_specs)
def set_field_value(self, row, field, value):
with self.table[row] as rd:
setattr(rd, field, value)
def set_value_by_index(self, row, col, value):
with self.table[row] as rd:
rd[col] = value
def close(self):
self.table.close()
def get_field_names(self):
return list(self.table.field_names)
def convert_list_dict(self):
field_nams = list(self.table.field_names)
return [ dict(zip(field_nams,list(record))) for record in dd.table]
def delete_fields(self,fields):
"""
删除对应列及数据
:param fields:
:return:
"""
self.table.delete_fields(fields)
def delete(self,row):
dbf.delete(self.table[row])
self.table.pack()
def get_field_names(self):
return list(self.table.field_names)
def get_field_specs(self):
field_list = self.table.structure()
return ';'.join(field_list)
def get_row_data(self,index):
return self.table[index][::]
if __name__ == '__main__':
dd = DbfHelper('temptable11.dbf')
data = [('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)),]
# print(dd.table[2])
# print(type(dd.table[2]))
# print(dd.table[2].name)
# dd.table[2].name = 'sdfsgdgb'
# print(dd.table[2])
# #dd.append_data(data)
# #dd.append_data(data)
# #dd.close()
# #dd.add_fields('tt1 C(30); tt2 N(3,0)')
# dd.close()
for record in dd.table:
print(record)
# for record in dd.table:
# with record as red:
# red[0] = '12133111'
#
# with dd.table[0] as rd:
# rd[0] = 'skjdhfgbshdfhhs'
#
# print(dd.table[0])
# print(getattr(dd.table[0], 'name'))
# with dd.table[0] as rd:
# setattr(rd, 'name', 'eee')
# print(dd.table[0])
# for record in dd.table:
# print(record)
#print(dd.convert_list_dict())
#dd.table.delete_fields('TT1')
#dd.table.pack()
dbf.delete(dd.table[0])
print("================================")
dd.table.pack()
for record in dd.table:
print(record)
3. Error reporting and resolution
3.1 ascii codec cant decode byte 0xd6 in position
solve:
codepage指定编码格式:
cp936 -- gb2312
import dbf
codepage_list = ['936', '437', ...]
tabel = dbf.Table('mydbf.dbf', codepage='cp{}'.format(codepage))
4. Reference documents
Official: dbf · PyPI