Python使用dbf库操作FoxPro DBF文件后字段精度丢失问题求助
Python使用dbf库操作FoxPro DBF文件后字段精度丢失问题求助
我来帮你捋捋这个问题,结合你描述的场景和代码来看,这个字段小数位丢失的情况,主要是因为Python的dbf库和VisualFoxPro(VFP)在处理双精度字段元数据的方式上有差异。
问题原因分析
- VFP里的
Double类型除了存储浮点数值,还会单独记录字段的小数位数信息;但dbf库默认读取时,会把这个字段识别成B binary类型,并没有完整保留VFP的小数位元数据。 - 当你修改表结构(比如添加新字段)或者新建表复制数据时,dbf库会用自身默认的dbf格式来写入表的元数据,这就导致VFP重新读取时,无法识别原来的小数位数,默认显示成0位。
解决办法
你可以试试下面这几个方案,应该能解决问题:
打开表时指定VFP格式
dbf库支持指定表的格式为VFP,只要在初始化dbf.Table时加上format='vfp'参数,库就会按照VFP的规则处理字段元数据,包括保留双精度字段的小数位数。修改后的初始化代码:rs_refr = dbf.Table('rs_refr.dbf', codepage='cp1252', ignore_memos=True, format='vfp')合并字段添加操作
你的代码里分两次调用add_fields,多次修改表结构可能会触发元数据重新写入,增加出错概率。建议把两个字段一次性添加:rs_refr.add_fields('UT_WT N(5,2), WT_UT N(5,2)')修正表的关闭方式
你代码最后用db.close(),这里应该是笔误,要对应你打开的表对象rs_refr来关闭,确保所有元数据都正确写入磁盘:rs_refr.close()新建表时手动指定字段类型
如果是通过新建表复制数据的方式,不要依赖库自动识别原表字段,手动指定DISTANCE字段的类型(对应VFP的Double(8,3),在dbf库中用B(8,3)表示):# 先打开原表 rs_refr = dbf.Table('rs_refr.dbf', codepage='cp1252', ignore_memos=True, format='vfp') rs_refr.open(dbf.READ_ONLY) # 创建新表,明确指定所有字段 new_table = dbf.Table( 'new_rs_refr.dbf', fields=[ 'DISTANCE B(8,3)', # 对应VFP的Double类型,宽度8,小数3位 # 这里补充原表的其他字段,比如WT字段的定义 'WT N(...)', 'UT_WT N(5,2)', 'WT_UT N(5,2)' ], codepage='cp1252', format='vfp' ) new_table.open(dbf.READ_WRITE) # 复制原表数据到新表 for record in rs_refr: new_table.append(record) # 关闭两个表 rs_refr.close() new_table.close()
按照上面的方法修改后,你再用VFP打开表,应该就能看到DISTANCE字段保持原来的Double, width - 8, decimal - 3格式了。如果还是有问题,可以试试用dbf库的dbf.copy_table方法,指定format='vfp'来复制表,这样能更完整地保留原表的字段属性。
备注:内容来源于stack exchange,提问作者Viktor
相关产品推荐
相关产品推荐

