在 Anaconda 下的 Python 3.6.3 中,我尝试读取一个包含备忘录数据的 dbf 文件。该文件是从商业软件中导出的。我使用 dbf 包,版本 0.97.11。文件类型为:
In [10]: dbf.table_type('C:\\Users\\kmec\\Documents\\Python Scripts\\misc\\test_dbf\\RelLinks.dbf')
Out[10]: (131, 'dBase III Plus w/memos')
该文件有一个随附的 dbt 文件 RelLinks.DBT(约 460 MB),位于与 dbf 文件相同的文件夹中。我的理解是(基于http://dbf-software.com/memo-blob.html),备忘录数据存储在 .DBT 文件中。因此,我假设以下代码应该可以工作:
d=dbf.Table( 'C:\\Users\\kmec\\Documents\\Python Scripts\\misc\\test_dbf\\RelLinks.dbf', ignore_memos=False, codepage='cp852')
d.open()
rellinks = []
for record in d[:10]:
print(record)
rellinks.append([record.id, record.srcyear, record.srcid, record.dstyear, record.dstid])
d.close()
rl = pd.DataFrame.from_records(rellinks, columns = ['rl_id', 'rl_srcyear', 'rl_srcid', 'rl_dstyear', 'rl_dstid'] )
但是,IPython 控制台(在 Spyder 3.3.1 下)中的“out”提示永远不会出现,所以我需要关闭控制台。
当设置ignore_memos = True
代码运行时,当然数据框中带有备忘录数据的结果列是空的。那么有没有办法在这种情况下读取带有备忘录数据的 dbf 文件呢?
编辑:
print(d)
结果是:
表:C:\Users\kmec\Documents\Python Scripts\misc\test_dbf\RelLinks.dbf
Type: dBase III Plus
Codepage: ascii (plain ol' ascii)
Status: DbfStatus.READ_ONLY
Last updated: 2020-06-25
Record count: 131847
Field count: 14
Record length: 146
--Fields--
0) id N(11,0)
1) reltype M
2) subreltype M
3) srcyear M
4) srctype M
5) srcid N(11,0)
6) srcitemtyp M
7) srcitemid N(11,0)
8) dstyear M
9) dsttype M
10) dstid N(11,0)
11) dstitemtyp M
12) dstitemid N(11,0)
13) mjvazba M
print(d)
before 和 afterd.open()
仅将状态从 CLOSED 更改为 READ_ONLY (非常符合预期)
原来codepage不是cp852而是ascii。
修复此问题后
d=dbf.Table( 'C:\\Users\\kmec\\Documents\\Python Scripts\\misc\\test_dbf\\RelLinks.dbf', ignore_memos=False, codepage='ascii')
并执行
for record in d[:10]:
print(record)
它像以前一样冻结,但 ctrl+C 强制使用以下输出进行键盘中断:
Traceback (most recent call last):
File "<ipython-input-24-902d684f24ef>", line 3, in <module>
print(record)
File "C:\Users\kmec\Anaconda3\lib\site-packages\dbf\__init__.py", line 3024, in __str__
result.append("%3d - %-10s: %r" % (seq, field, self[field]))
File "C:\Users\kmec\Anaconda3\lib\site-packages\dbf\__init__.py", line 2956, in __getitem__
return self.__getattr__(item)
File "C:\Users\kmec\Anaconda3\lib\site-packages\dbf\__init__.py", line 2923, in __getattr__
value = self._retrieve_field_value(name)
File "C:\Users\kmec\Anaconda3\lib\site-packages\dbf\__init__.py", line 3122, in _retrieve_field_value
datum = retrieve(record_data, fielddef, self._meta.memo, self._meta.decoder)
File "C:\Users\kmec\Anaconda3\lib\site-packages\dbf\__init__.py", line 4058, in retrieve_memo
data = memo.get_memo(block)
File "C:\Users\kmec\Anaconda3\lib\site-packages\dbf\__init__.py", line 3607, in get_memo
return self._get_memo(block)
File "C:\Users\kmec\Anaconda3\lib\site-packages\dbf\__init__.py", line 3655, in _get_memo
newdata = self.meta.mfd.read(self.meta.memo_size)
KeyboardInterrupt