一.前言:
网上有些使用dbfpy,dbfread库操作dbf文件的实例,个人对比了一些操作库,最终选用dbf库,因为
dbf库能完成增删改查操作且一直有更新所以使用此库进行封装
可视化操作软件:个人推荐DBFViewerPlus,比较快,而且打开大文件不卡顿
二.自己封装的dbf文件操作库
列定义
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.1 ascii codec cant decode byte 0xd6 in position
解决:
codepage指定编码格式:
cp936 -- gb2312
import dbf
codepage_list = ['936', '437', ...]
tabel = dbf.Table('mydbf.dbf', codepage='cp{}'.format(codepage))
四.参考文档
官方:dbf · PyPI