csv format to DBase III format

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • coriolis_wong@yahoo.com.hk

    #1

    csv format to DBase III format

    Hi,

    I need to transfer csv format file to DBase III format file.
    How do i do it in Python language?


    Any help is appreciated.
    Thanks.

  • Peter Otten

    #2
    Re: csv format to DBase III format

    coriolis_wong@y ahoo.com.hk wrote:
    [color=blue]
    > I need to transfer csv format file to DBase III format file.
    > How do i do it in Python language?[/color]



    Peter

    Comment

    • William

      #3
      Re: csv format to DBase III format


      Peter Otten wrote:[color=blue]
      > coriolis_wong@y ahoo.com.hk wrote:
      >[color=green]
      > > I need to transfer csv format file to DBase III format file.
      > > How do i do it in Python language?[/color]
      >
      > http://aspn.activestate.com/ASPN/Coo.../Recipe/362715
      >
      > Peter[/color]

      Hi,

      I create a dbf file, it can be opened by Excel but it cannot be opened
      by Access. Where
      is the error in my script. My script is as follows:

      #!/opt/bin/python2.3

      import struct, datetime,iterto ols,time


      def dbfwriter(f, fieldnames, fieldspecs, records):

      """ Return a string suitable for writing directly to a binary dbf
      file.

      File f should be open for writing in a binary mode.

      Fieldnames should be no longer than ten characters and not include
      \x00.
      Fieldspecs are in the form (type, size, deci) where
      type is one of:
      C for ascii character data
      M for ascii character memo data (real memo fields not
      supported)
      D for datetime objects
      N for ints or decimal objects
      L for logical values 'T', 'F', or '?'
      size is the field width
      deci is the number of decimal places in the provided decimal
      object
      Records can be an iterable over the records (sequences of field
      values).

      """
      # header info
      ver = 3
      now = datetime.dateti me.now()
      yr, mon, day = now.year-1900, now.month, now.day
      numrec = len(records)
      numfields = len(fieldspecs)
      lenheader = numfields * 32 + 33
      # lenrecord = sum(field[1] for field in fieldspecs) + 1
      num = 0
      for field in fieldspecs :
      num = num + int(field[1])

      lenrecord = num + 1

      hdr = struct.pack('<B BBBLHH20x', ver, yr, mon, day, numrec,
      lenheader, lenrecord)
      f.write(hdr)

      # field specs
      for name, (typ, size, deci) in itertools.izip( fieldnames,
      fieldspecs):
      # name = name.ljust(11, '\x00')
      name = name.ljust(11)
      fld = struct.pack('<1 1sc4xBB14x', name, typ, size, deci)
      f.write(fld)

      # terminator
      f.write('\r')

      # records
      for record in records:
      f.write(' ') # deletion flag
      for (typ, size, deci), value in itertools.izip( fieldspecs,
      record):
      if typ == "N":
      # value = str(value).rjus t(size, ' ')
      value = str(value).rjus t(size)
      elif typ == 'D':
      # value = value.strftime( '%Y%m%d')
      value = value
      elif typ == 'L':
      value = str(value)[0].upper()
      else:
      # value = str(value)[:size].ljust(size, ' ')
      value = str(value)[:size].ljust(size)
      assert len(value) == size
      f.write(value)

      # End of file
      f.write('\x1A')
      f.close()


      # -------------------------------------------------------
      # Example calls
      if __name__ == '__main__':

      import sys, csv
      from cStringIO import StringIO
      # from operator import itemgetter


      # Create a new DBF
      # f = StringIO()

      f = open('test.dbf' ,'w')
      fieldnames = ['CUSTOMER_ID',' EMPLOY_ID','ORD ER_DATE','ORDER _AMT']
      fieldspecs = [('C',11,0),('C' ,11,0),('D',8,0 ),('N',12,2)]
      records = [['MORNS','555',' 19950626','17.4 0'],\
      ['SAWYH','777',' 19950629','97.3 0'],\
      ['WALNG','555',' 19950522','173. 40']]


      dbfwriter(f, fieldnames, fieldspecs, records)

      Thanks,

      William

      Comment

      • coriolis_wong@yahoo.com.hk

        #4
        Re: csv format to DBase III format


        Peter Otten wrote:[color=blue]
        > coriolis_wong@y ahoo.com.hk wrote:
        >[color=green]
        > > I need to transfer csv format file to DBase III format file.
        > > How do i do it in Python language?[/color]
        >
        > http://aspn.activestate.com/ASPN/Coo.../Recipe/362715
        >
        > Peter[/color]

        Hi,

        I create a dbf file, it can be opened by Excel but it cannot be opened
        by Access. Where is the error in my script. My script is as follows,

        def dbfwriter(f, fieldnames, fieldspecs, records):
        """ Return a string suitable for writing directly to a binary dbf
        file.

        File f should be open for writing in a binary mode.

        Fieldnames should be no longer than ten characters and not include
        \x00.
        Fieldspecs are in the form (type, size, deci) where
        type is one of:
        C for ascii character data
        M for ascii character memo data (real memo fields not
        supported)
        D for datetime objects
        N for ints or decimal objects
        L for logical values 'T', 'F', or '?'
        size is the field width
        deci is the number of decimal places in the provided decimal
        object
        Records can be an iterable over the records (sequences of field
        values).

        """
        # header info
        ver = 3
        now = datetime.dateti me.now()
        yr, mon, day = now.year-1900, now.month, now.day
        numrec = len(records)
        numfields = len(fieldspecs)
        lenheader = numfields * 32 + 33
        # lenrecord = sum(field[1] for field in fieldspecs) + 1
        num = 0
        for field in fieldspecs :
        num = num + int(field[1])

        lenrecord = num + 1

        hdr = struct.pack('<B BBBLHH20x', ver, yr, mon, day, numrec,
        lenheader, lenrecord)
        f.write(hdr)

        # field specs
        for name, (typ, size, deci) in itertools.izip( fieldnames,
        fieldspecs):
        # name = name.ljust(11, '\x00')
        name = name.ljust(11)
        fld = struct.pack('<1 1sc4xBB14x', name, typ, size, deci)
        f.write(fld)

        # terminator
        f.write('\r')

        # records
        for record in records:
        f.write(' ') # deletion flag
        for (typ, size, deci), value in itertools.izip( fieldspecs,
        record):
        if typ == "N":
        # value = str(value).rjus t(size, ' ')
        value = str(value).rjus t(size)
        elif typ == 'D':
        # value = value.strftime( '%Y%m%d')
        value = value
        elif typ == 'L':
        value = str(value)[0].upper()
        else:
        # value = str(value)[:size].ljust(size, ' ')
        value = str(value)[:size].ljust(size)
        assert len(value) == size
        f.write(value)

        # End of file
        f.write('\x1A')
        f.close()


        # -------------------------------------------------------
        # Example calls
        if __name__ == '__main__':

        import sys, csv
        from cStringIO import StringIO
        # from operator import itemgetter


        # Create a new DBF
        # f = StringIO()

        f = open('test.dbf' ,'w')
        fieldnames = ['CUSTOMER_ID',' EMPLOY_ID','ORD ER_DATE','ORDER _AMT']
        fieldspecs = [('C',11,0),('C' ,11,0),('D',8,0 ),('N',12,2)]
        records = [['MORNS','555',' 19950626','17.4 0'],\
        ['SAWYH','777',' 19950629','97.3 0'],\
        ['WALNG','555',' 19950522','173. 40']]


        dbfwriter(f, fieldnames, fieldspecs, records)



        William

        Comment

        • Peter Otten

          #5
          Re: csv format to DBase III format

          William wrote:
          [color=blue]
          > Peter Otten wrote:[color=green]
          >> coriolis_wong@y ahoo.com.hk wrote:
          >>[color=darkred]
          >> > I need to transfer csv format file to DBase III format file.
          >> > How do i do it in Python language?[/color]
          >>
          >> http://aspn.activestate.com/ASPN/Coo.../Recipe/362715[/color][/color]
          [color=blue]
          > I create a dbf file, it can be opened by Excel but it cannot be opened
          > by Access. Where is the error in my script.[/color]

          No idea, but here's some brainstorming.
          [color=blue]
          > f = open('test.dbf' ,'w')[/color]

          First make sure that you open the file in binary mode 'wb'.
          If you have an application around that can generate dbfs you could compare a
          manually created file with the python-generated one. Have you tried the dbf
          with no records? If that is opened without error, you could successively
          add records until you find the culprit. Finally, if Excel and Access
          disagree about the dbf's validity, the Access import filter could be
          broken. Are there other filters for the Dbase family (Foxpro, Clipper)? Try
          one of them.

          Peter

          Comment

          • William

            #6
            Re: csv format to DBase III format


            Peter Otten wrote:[color=blue]
            > William wrote:
            >[color=green]
            > > Peter Otten wrote:[color=darkred]
            > >> coriolis_wong@y ahoo.com.hk wrote:
            > >>
            > >> > I need to transfer csv format file to DBase III format file.
            > >> > How do i do it in Python language?
            > >>
            > >> http://aspn.activestate.com/ASPN/Coo.../Recipe/362715[/color][/color]
            >[color=green]
            > > I create a dbf file, it can be opened by Excel but it cannot be opened
            > > by Access. Where is the error in my script.[/color]
            >
            > No idea, but here's some brainstorming.
            >[color=green]
            > > f = open('test.dbf' ,'w')[/color]
            >
            > First make sure that you open the file in binary mode 'wb'.
            > If you have an application around that can generate dbfs you could compare a
            > manually created file with the python-generated one. Have you tried the dbf
            > with no records? If that is opened without error, you could successively
            > add records until you find the culprit. Finally, if Excel and Access
            > disagree about the dbf's validity, the Access import filter could be
            > broken. Are there other filters for the Dbase family (Foxpro, Clipper)? Try
            > one of them.
            >
            > Peter[/color]

            I have no idea too. I use Foxpro to open the file, but it is failure.
            The warning message
            is as follows
            "Either the table record count does not match the actual records in the
            table, or the file size on the disk does not match the expected file
            size from the table header."

            Anybody have any idea?

            William

            Comment

            • Thomas Ganss

              #7
              Re: csv format to DBase III format

              Hi,
              [color=blue][color=green][color=darkred]
              >>>>>I need to transfer csv format file to DBase III format file.
              >>>>>How do i do it in Python language?
              >>>>
              >>>>http://aspn.activestate.com/ASPN/Coo.../Recipe/362715[/color]
              >>[color=darkred]
              >>>I create a dbf file, it can be opened by Excel but it cannot be opened
              >>>by Access. Where is the error in my script.[/color][/color][/color]
              ....>[color=blue]
              > I have no idea too. I use Foxpro to open the file, but it is failure.
              > The warning message is as follows
              > "Either the table record count does not match the actual records in the
              > table, or the file size on the disk does not match the expected file
              > size from the table header."[/color]

              The error message is quite clear -
              in the .dbf format the record count is written to the file header.

              The filesize should be record_count*re cordsize + headersize.

              There are some options to fix a dbf, even via foxpro.
              Comparing file size / header info should point you to your error.

              Such a task (if targeted to run on a win machine) is probably
              better done in foxpro or another dbase clone / file handler:
              would take probably less a handful of lines and be much safer.


              my 0.02 EUR

              thomas

              Comment

              Working...