python(43): dbf file reading and writing, error resolution

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

Python Write value in dbf file - Stack Overflow

Guess you like

Origin blog.csdn.net/qq_37674086/article/details/125885945