2

在 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  
4

1 回答 1

0

我无法在 dbf 模块中找到问题。我的猜测是你要么有内存问题(每个备忘录字段的数据在 3 到 400 万字节之间),要么你的硬盘驱动器速度慢,或者两者兼而有之。

于 2020-06-30T18:35:38.283 回答