Bulk Convert DBF To CSV In A Folder ArcGIS 10.1 Using Python


Answer :

I have only tested this very briefly (and with a limited variety of data), but this script demonstrates one way this might be accomplished:

import arcpy import csv import os import codecs import cStringIO  def batch_convert_dbf_to_csv(input_dir, output_dir, rename_func=None):     """Converts shapefiles and standalone DBF tables within the input directory     input_dir to CSV files within the output directory output_dir. An     optional function rename_func may be used to manipulate the output file     name."""     # Set workspace to input directory     arcpy.env.workspace = input_dir      # List shapefiles and standalone DBF tables in workspace     tables = list_tables()      # Only proceed if there actually exists one or more shapefiles or DBF tables     if tables:         # Create output directory structure         make_output_dir(output_dir)          # Loop over shapefiles and DBF tables         for table in tables:             # Generate output filename             output_name = os.path.splitext(os.path.basename(table))[0]             if rename_func:                 output_name = rename_func(output_name)             output_csv_file = os.path.join(output_dir,                 output_name + os.extsep + 'csv')              # List input fields             fields = list_fields(table)              # Open input table for reading             rows = read_rows(table, fields)              # Set flag indicating whether we are overwriting an existing file             output_exists = os.path.isfile(output_csv_file)              # Attempt to create output CSV file             try:                 write_unicode_csv(output_csv_file, rows, fields)                  # Warn if we overwrite anything                 if output_exists:                     print 'warning: overwrote {0}'.format(output_csv_file)                 else:                     print 'wrote {0}'.format(output_csv_file)             except IOError:                 print 'warning: unable to create output CSV file {0}'.format(                     output_csv_file)     else:         print 'No DBF files found in workspace {0}'.format(input_dir)  def list_tables():     """Returns a list of shapefiles and standalone DBF tables in the current     workspace."""     tables = arcpy.ListFeatureClasses('*.shp')     tables.extend(arcpy.ListTables('*', 'dBASE'))     return tables  def list_fields(table):     """Returns a list of fields in the specified table, excluding the shape     field if present."""     desc = arcpy.Describe(table)     shape_field_name = desc.shapeFieldName if hasattr(         desc, 'shapeFieldName') else ''     return [field.name for field in desc.fields         if field.name != shape_field_name]  def read_rows(table, fields='*'):     """Generator function that yields the rows of a table, including only the     specified fields."""     with arcpy.da.SearchCursor(table, fields) as rows:         for row in rows:             yield row  def write_unicode_csv(output_csv, rows, header_row=None):     """Creates a UTF-8 encoded CSV file specified by output_csv containing the     specified rows and the optional header_row."""     with open(output_csv, 'wb') as f:         f.write(codecs.BOM_UTF8) # Write Byte Order Mark character so Excel                                  # knows this is a UTF-8 file         csv_writer = UnicodeWriter(f, dialect='excel', encoding='utf-8')         if header_row:             csv_writer.writerow(header_row)         csv_writer.writerows(rows)  def make_output_dir(path):     """Creates the output directory structure if it does not already exist."""     if not os.path.isdir(path):         try:             os.makedirs(path)             print 'created dir {0}'.format(path)         except OSError:             if not os.path.isdir(path):                 raise  class UnicodeWriter:     """     A CSV writer which will write rows to CSV file 'f',     which is encoded in the given encoding.     Based on: https://docs.python.org/2/library/csv.html#examples     """      def __init__(self, f, dialect=csv.excel, encoding='utf-8', **kwds):         # Redirect output to a queue         self.queue = cStringIO.StringIO()         self.writer = csv.writer(self.queue, dialect=dialect, **kwds)         self.stream = f         self.encoder = codecs.getincrementalencoder(encoding)()      def writerow(self, row):         self.writer.writerow([str(s).encode('utf-8') for s in row])         # Fetch UTF-8 output from the queue ...         data = self.queue.getvalue()         data = data.decode('utf-8')         # ... and reencode it into the target encoding         data = self.encoder.encode(data)         # write to the target stream         self.stream.write(data)         # empty queue         self.queue.truncate(0)      def writerows(self, rows):         for row in rows:             self.writerow(row)  if __name__ == '__main__':     # Configure script here, or modify to take parameters/arguments     input_dir = r'path\to\input_directory'     output_dir = r'path\to\output_directory'      # Customize this function to change renaming logic     def rename_func(input_name, default='output'):         # Strips non-digits from string         output_name = ''.join((char for char in input_name if char.isdigit()))          # Give filename a sensible default name if there are no digits         return output_name or default      # Run it     batch_convert_dbf_to_csv(input_dir, output_dir, rename_func) 

This does not take any arguments/parameters so I leave that up to you. If you want to implement it as a script tool or Python toolbox, read the appropriate ESRI documentation.

It attempts some defensive coding techniques for things like mixed shapefile and standalone DBF content, omitting Shape fields, non-ASCII characters, non-existent directories, warning when it overwrites existing files, etc., but as I said, not well tested, so use at your own risk!


This should work for both shapefile and separate dbf file

import os import arcpy import csv  def dbf2csv(dbfpath, csvpath):     ''' To convert .dbf file or any shapefile/featureclass to csv file     Inputs:          dbfpath: full path to .dbf file [input] or featureclass         csvpath: full path to .csv file [output]      '''     #import csv     rows = arcpy.SearchCursor(dbfpath)     csvFile = csv.writer(open(csvpath, 'wb')) #output csv     fieldnames = [f.name for f in arcpy.ListFields(dbfpath)]      allRows = []     for row in rows:         rowlist = []         for field in fieldnames:             rowlist.append(row.getValue(field))         allRows.append(rowlist)      csvFile.writerow(fieldnames)     for row in allRows:         csvFile.writerow(row)     row = None     rows = None 

Call this function dbf2csv for every dbf file In your case 1000 times, this is just an example of calling, perhaps it will work for you without any modification

dbf_dir = 'S:/output_tables/' csv_dir = 'S:/output_tables/csv1/' for dbf_file in os.listdir(dbf_dir):     # Loop through all dbf files     # and export to dbf     fileName, fileExt = os.path.splitext(dbf_file)  #[0] or [1] for file     if '.dbf' in fileExt:         # construct full path to dbf file and csv file         dbfpath = os.path.join(dbf_dir, fileName+fileExt)         csvpath = os.path.join(csv_dir, fileName+'.csv')         if os.path.exists(dbfpath):             # this may not be necessary             #    print 'processing: ', dbfpath, csvpath                                 if not os.path.exists(csvpath):                 ## to prevent overwrite of existing csv file                 ## call the function to convert .dbf file to csv file                 print 'Export nexrad {0} to {1}'.format(dbfpath, csvpath)                 dbf2csv(dbfpath, csvpath) 

Since it this python, make sure the indentations are right


If you look for a full arcpy solution (without dbf) you can use

import glob glob.glob('S:\\output_tables\\*.dbf') 

for listing you tables, then

arcpy.ListFields()  

for the field names and

outname = os.path.basename(inputtable)[3:-4] + ".csv" 

to create your output names

and finally

arcpy.da.SearchCursor() 

to get a Python iterable that you can use directly with csv.writerow() (and even with csv.writerows() to e verified)


Comments

Popular posts from this blog

Converting A String To Int In Groovy

"Cannot Create Cache Directory /home//.composer/cache/repo/https---packagist.org/, Or Directory Is Not Writable. Proceeding Without Cache"

Android How Can I Convert A String To A Editable