Can't read from Visual FoxPro DBF file with CodePage cp874 data

1,061 views
Skip to first unread message

kiwi64ajs

unread,
Jan 19, 2013, 8:25:06 AM1/19/13
to python...@googlegroups.com
Hi

I'm trying to read library book data from a Visual FoxPro 3 DBF file using Python and the dbf library.

Here is the code I'm trying:
<pre>
from dbf import *
print Table("book.dbf")
for rec in Table("book.dbf"):
print rec
</pre>

I get the book.dbf fields printed out (see below) ok (two fields are in cp874 charsset) but then it throws an exception saying the database is closed, so I expect something is going wrong processing the header or something and causing the database to close or be closed.

Any help would be much appreciated.

Regards

Alex Shepherd
-----------------------------------------------------------------------------

Table: book.dbf
Type: Visual FoxPro
Codepage: cp874 (Thai (ANSI/OEM))
Status: closed
Last updated: 2013-01-20
Record count: 23660
Field count: 35
Record length: 766
--Fields--
0) print L
1) code C(10)
2) date C(10)
3) title C(100)
4) codebook C(15)
5) callnum01 C(15)
6) callnum02 C(15)
7) callnum03 C(15)
8) callnum04 C(15)
9) callnum05 C(15)
10) author01 C(50)
11) author02 C(30)
12) author03 C(30)
13) Í_ÉÃÂÍ C(5)
14) edition N(2,0)
15) printplace C(15)
16) imprint C(30)
17) yearprint C(6)
18) series C(50)
19) note C(80)
20) tracing C(80)
21) price N(9,2)
22) source C(50)
23) status C(10)
24) dateout C(10)
25) booktype C(10)
26) issn C(15)
27) isbn C(15)
28) npage N(6,0)
29) a_nset N(3,0)
30) a_lpicture L
31) a_ltable L
32) a_lmap L
33) ¹ÒÁὧ C(10)
34) type C(35)

Traceback (most recent call last):
File "book.py", line 5, in <module>
for rec in Table("book.dbf"):
File "/usr/local/lib/python2.6/dist-packages/dbf.py", line 2945, in next
record = self._table[self._index]
File "/usr/local/lib/python2.6/dist-packages/dbf.py", line 3384, in __getitem__
return self._table[value]
File "/usr/local/lib/python2.6/dist-packages/dbf.py", line 3175, in __getitem__
raise DbfError("%s is closed; record %d is unavailable" % (meta.filename, index))
dbf.DbfError: book.dbf is closed; record 0 is unavailable

Ethan Furman

unread,
Jan 21, 2013, 12:57:29 PM1/21/13
to python...@googlegroups.com
On 01/19/2013 05:25 AM, kiwi64ajs wrote:
> Hi

Hello!


> I'm trying to read library book data from a Visual FoxPro 3 DBF file using Python and the dbf library.
>
> Here is the code I'm trying:
> <pre>
> from dbf import *
> print Table("book.dbf")
> for rec in Table("book.dbf"):
> print rec
> </pre>

`Table` returns a table every time you call it. You should save the
result from one call so you're not creating several links to the same
file as that can result in data corruption.

Here's what you should do:

from dbf import *
book_data = Table("book.dbf")
book_data.open()
for rec in book_data:
print rec
book_data.close()

if you are using a Python that supports `with` you could also do it this
way:

from dbf import *
book_data = Table("book.dbf")
with book_data:
for rec in book_data:
print rec

and `book_data` will be automatically opened and closed for you.

A couple notes you may not be aware of: `from whatever import *` should
only be used with modules/packages that were designed for it -- if they
don't say they support it, assume they don't (mine is); even if the
module/package does support it, you might be better off just importing
the pieces you need:

from dbf import Table, List

> I get the book.dbf fields printed out (see below) ok (two fields are in cp874 charsset) [...]

Hopefully /all/ the fields are in cp874 -- if not, you may have to do
some extra coding to properly decode the fields that aren't.


> Any help would be much appreciated.

Let me know if you get stuck anywhere else.

~Ethan~

Alex Shepherd

unread,
Jan 21, 2013, 4:31:06 PM1/21/13
to python...@googlegroups.com
Hi Ethan,

> > I'm trying to read library book data from a Visual FoxPro 3 DBF file using
> Python and the dbf library.
> >
> > Here is the code I'm trying:
> > <pre>
> > from dbf import *
> > print Table("book.dbf")
> > for rec in Table("book.dbf"):
> > print rec
> > </pre>
>
> `Table` returns a table every time you call it. You should save the result from
> one call so you're not creating several links to the same file as that can result
> in data corruption.
>
> Here's what you should do:
>
> from dbf import *
> book_data = Table("book.dbf")
> book_data.open()
> for rec in book_data:
> print rec
> book_data.close()

Hmmm... ok I thought I had try this combination already but I pasted your code in and it worked so obviously I had not... ;(

The reason I tried your Python code was because I couldn't get the equivalent going in PERL, which was where I had started. I also need to write the output in the MARC library interchange format and have used the PERL MARC library before.

After not getting far with the Python option I went back to PERL and the penny dropped and I got it working, but I see there is a Python MARC library so I might give that a go as well as I find Python more understandable than PERL...

> > I get the book.dbf fields printed out (see below) ok (two fields are
> > in cp874 charsset) [...]
>
> Hopefully /all/ the fields are in cp874 -- if not, you may have to do some extra
> coding to properly decode the fields that aren't.

Yes I expect so.

I just need to figure out the UNICODE side of Python and then I can probably display the records properly - currently it complains about missing codepage mappings, but that is more than I had...

Thanks for the help

Alex

Reply all
Reply to author
Forward
0 new messages