1

I am trying to insert a python list of tuples to arcgis table. there is type mismatch which is obvious. Each Value in tuples have different type and fields in table have different data types.

So, how can I loop through each field, check data type, perform type cast on each values in python tuples and insert them in table. Or is there easier way to do this ?

   pylist= [(1.0, u'10',''), (2.0, 1.0, 2.0), (u'9', '', 2.0)]
   fields =["A", "B", "C"]  #fields of arcgis table


  row = arcpy.da.InsertCursor(tablename, fields )
  for i in range(len(pylist)):
  # here i need to have a routine which checks the data type of the field and perform type cast on tuple value before insertion
        row.insertRow(pylist[i])

Any suggestion will be helpful.

1 Answer 1

4

Since the field datatypes are static, you can pre-cast pylist to whatever you need it to be. For example:

pylist= [(1.0, u'10',''), (2.0, 1.0, 2.0), (u'9', '', 2.0)]
cast = [(float(x), str(y), str(z)) for x,y,z in pylist]
#[(1.0, '10', ''), (2.0, '1.0', '2.0'), (9.0, '', '2.0')]

fields =["A", "B", "C"]  #fields of arcgis table

#using with means closure in the event of completion/failure
with arcpy.da.InsertCursor(tablename, fields) as row:
  for triplet in cast: #Don't need to use indexing
    row.insertRow(triplet)

You'll just need to make sure that pylist actually supports what you are casting to.

Edit: The solution is to use class, although this isn't the prettiest way to do it. getattr() is handy here.

class Caster:
    def __init__(self, val):
        self.val = val

    def to_int(self):
        return int(self.val)
    def to_str(self):
        return str(self.val)    
    def to_float(self):
        return float(self.val)

pylist= [(1.0, u'10',''), (2.0, 1.0, 2.0), (u'9', '', 2.0)]

fields =["A", "B", "C"]  #fields of arcgis table

#Create list of field types for existing names
ftypes = [f.type for f in arcpy.ListFields(tablename) if f.name in fields]
ftypes = ["DOUBLE", "TEXT", "TEXT"]
#Create dictionary of the form fieldtype:<Caster method name>
fdict = dict([("SHORT", "to_int"), ("LONG", "to_int"), ("TEXT", "to_str"), ("DOUBLE", "to_float")])
types = [fdict[t] for t in ftypes] #List of builtin cast functions as strings  

cast = [[getattr(Caster(val), types[i])() for i,val in enumerate(vals)] for vals in pylist]

#using with means closure in the event of completion/failure
with arcpy.da.InsertCursor(tablename, fields) as row:
  for triplet in cast: #Don't need to use indexing
    row.insertRow(triplet)
7
  • I'm assuming that pylist isn't normally static, but presented that way here as an example. I could be wrong though.
    – ianbroad
    Aug 27, 2015 at 16:41
  • @Ian yes. you are right it is not static. it is only an example.
    – Jio
    Aug 27, 2015 at 16:50
  • @Larry, the field types are static, i.e., it can't change during the insertcursor. cast works for the example pylist you gave. I just gave examples of datatypes for the various fields.
    – Paul
    Aug 27, 2015 at 17:34
  • @Paul, Yes so basically, before 'insertcursor' i need to check the data type of each tuple value and change it to that of the field if they are not same. I need a routine for that .
    – Jio
    Aug 27, 2015 at 17:53
  • 1
    @Larry, have fun with my edit. It should be extensible to any number of fields.
    – Paul
    Aug 27, 2015 at 20:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.