Looked more closely at problem on how to add data to a shapefile using fiona. Docs for fiona very unclear on how to do this. I know how to add a schema after that looks very unwieldy and can not figure things out. So has anyone just done a join (out side of fiona) and added data to shape file using fiona. A reasonably large file not just one record. I know how to join data just start from there. You have a shape file get the data for the record attributes join it then what? Seems easy. Really just use the bottom part for historical reference.

OK coped shape and added new schema with ordereddict and successfully (I think). Then using append in fiona I just want to add data using ordereddict or something like that to properties data. See code below. The variables are matched up but keep getting error. TypeError: string indices must be integers, not str

I don't know how it wants the data input or something else is the problem.

Below is the code and the ordereddicts I am using. I use the write funtion to add new Schema first then append data to add variables to shapefile. I think that was the way to do it.

bx = 0

with fiona.open(
    driver = source_driver,
    crs = source_crs,

    schema={'geometry': 'Polygon','properties': wschema,}) as c:
    print len(c)

    print c.schema


{'geometry': 'Polygon', 'properties': OrderedDict([(u'scalerank', 'int:4'), (u'featurecla', 'str:30'), (u'labelrank', 'float:16.6'), (u'sovereignt', 'str:254'), (u'sov_a3', 'str:254'), (u'adm0_dif', 'float:16.6'), (u'level', 'float:16.6'), (u'type', 'str:254'), (u'admin', 'str:254'), (u'adm0_a3', 'str:254'), (u'geou_dif', 'float:16.6'), (u'geounit', 'str:254'), (u'gu_a3', 'str:254'), (u'su_dif', 'float:16.6'), (u'subunit', 'str:254'), (u'su_a3', 'str:254'), (u'brk_diff', 'float:16.6'), (u'name', 'str:254'), (u'name_long', 'str:254'), (u'brk_a3', 'str:254'), (u'brk_name', 'str:254'), (u'brk_group', 'str:254'), (u'abbrev', 'str:254'), (u'postal', 'str:254'), (u'formal_en', 'str:254'), (u'formal_fr', 'str:254'), (u'note_adm0', 'str:254'), (u'note_brk', 'str:254'), (u'name_sort', 'str:254'), (u'name_alt', 'str:254'), (u'mapcolor7', 'float:16.6'), (u'mapcolor8', 'float:16.6'), (u'mapcolor9', 'float:16.6'), (u'mapcolor13', 'float:16.6'), (u'pop_est', 'float:16.6'), (u'gdp_md_est', 'float:16.6'), (u'pop_year', 'float:16.6'), (u'lastcensus', 'float:16.6'), (u'gdp_year', 'float:16.6'), (u'economy', 'str:254'), (u'income_grp', 'str:254'), (u'wikipedia', 'float:16.6'), (u'fips_10', 'str:254'), (u'iso_a2', 'str:254'), (u'iso_a3', 'str:254'), (u'iso_n3', 'str:254'), (u'un_a3', 'str:254'), (u'wb_a2', 'str:254'), (u'wb_a3', 'str:254'), (u'woe_id', 'float:16.6'), (u'adm0_a3_is', 'str:254'), (u'adm0_a3_us', 'str:254'), (u'adm0_a3_un', 'float:16.6'), (u'adm0_a3_wb', 'float:16.6'), (u'continent', 'str:254'), (u'region_un', 'str:254'), (u'subregion', 'str:254'), (u'region_wb', 'str:254'), (u'name_len', 'float:16.6'), (u'long_len', 'float:16.6'), (u'abbrev_len', 'float:16.6'), (u'tiny', 'float:16.6'), (u'homepart', 'float:16.6'), ('Country', 'str:254'), ('Index', 'str:38'), ('A2', 'str:254'), ('A3', 'str:254'), ('Code', 'str:38'), ('1', 'str:38'), ('730', 'str:38'), ('1000', 'str:38'), ('1150', 'str:38'), ('1280', 'str:38'), ('1300', 'str:38'), ('1348', 'str:38'), ('1400', 'str:38'), ('1450', 'str:38'), ('1500', 'str:38'), ('1550', 'str:38'), ('1570', 'str:38'), ('1600', 'str:38'), ('1650', 'str:38'), ('1700', 'str:38'), ('1720', 'str:38'), ('1750', 'str:38'), ('1775', 'str:38'), ('1800', 'str:38'), ('1820', 'str:38'), ('1850', 'str:38'), ('1870', 'str:38'), ('1890', 'str:38'), ('1913', 'str:38'), ('1929', 'str:38'), ('1950', 'str:38'), ('1960', 'str:38'), ('1973', 'str:38'), ('1980', 'str:38'), ('1990', 'str:38'), ('2000', 'str:38'), ('2008', 'str:38')])}

with fiona.open('/*/adata.shp', 'a') as cwt:

    kr = gh[0]

    print kr

    cwt.write({'geometry':'Polygon','properties': kr,})


TypeError Traceback (most recent call last) in () 2 kr = gh[0] 3 print kr ----> 4 cwt.write({'geometry':'Polygon','properties': kr,}) 5 close()

/home/matthew/Enthought/Canopy_32bit/User/lib/python2.7/site-packages/fiona/collection.pyc in write(self, record) 209 def write(self, record): 210 """Stages a record for writing to disk.""" --> 211 self.writerecords([record]) 212 213 def validate_record(self, record):

/home/matthew/Enthought/Canopy_32bit/User/lib/python2.7/site-packages/fiona/collection.pyc in writerecords(self, records) 203 if self.mode not in ('a', 'w'): 204 raise IOError("collection not open for writing") --> 205 self.session.writerecs(records, self) 206 self._len = self.session.get_length() 207 self._bounds = self.session.get_extent()

/home/matthew/Enthought/Canopy_32bit/User/lib/python2.7/site-packages/fiona/ogrext.so in fiona.ogrext.WritingSession.writerecs (src/fiona/ogrext.c:15787)()

/home/matthew/Enthought/Canopy_32bit/User/lib/python2.7/site-packages/fiona/ogrext.so in fiona.ogrext.WritingSession.writerecs.validate_geometry_type (src/fiona/ogrext.c:15230)()

TypeError: string indices must be integers, not str

OrderedDict([(u'scalerank', 1), (u'featurecla', u'Admin-0 map subunit'), (u'labelrank', 3.0), (u'sovereignt', u'Afghanistan'), (u'sov_a3', u'AFG'), (u'adm0_dif', 0.0), (u'level', 2.0), (u'type', u'Sovereign country'), (u'admin', u'Afghanistan'), (u'adm0_a3', u'AFG'), (u'geou_dif', 0.0), (u'geounit', u'Afghanistan'), (u'gu_a3', u'AFG'), (u'su_dif', 0.0), (u'subunit', u'Afghanistan'), (u'su_a3', u'AFG'), (u'brk_diff', 0.0), (u'name', u'Afghanistan'), (u'name_long', u'Afghanistan'), (u'brk_a3', u'AFG'), (u'brk_name', u'Afghanistan'), (u'brk_group', None), (u'abbrev', u'Afg.'), (u'postal', u'AF'), (u'formal_en', u'Islamic State of Afghanistan'), (u'formal_fr', None), (u'note_adm0', None), (u'note_brk', None), (u'name_sort', u'Afghanistan'), (u'name_alt', None), (u'mapcolor7', 5.0), (u'mapcolor8', 6.0), (u'mapcolor9', 8.0), (u'mapcolor13', 7.0), (u'pop_est', 28400000.0), (u'gdp_md_est', 22270.0), (u'pop_year', -99.0), (u'lastcensus', 1979.0), (u'gdp_year', -99.0), (u'economy', u'7. Least developed region'), (u'income_grp', u'5. Low income'), (u'wikipedia', -99.0), (u'fips_10', None), (u'iso_a2', u'AF'), (u'iso_a3', u'AFG'), (u'iso_n3', 4), (u'un_a3', u'004'), (u'wb_a2', u'AF'), (u'wb_a3', u'AFG'), (u'woe_id', -99.0), (u'adm0_a3_is', u'AFG'), (u'adm0_a3_us', u'AFG'), (u'adm0_a3_un', -99.0), (u'adm0_a3_wb', -99.0), (u'continent', u'Asia'), (u'region_un', u'Asia'), (u'subregion', u'Southern Asia'), (u'region_wb', u'South Asia'), (u'name_len', 11.0), (u'long_len', 11.0), (u'abbrev_len', 4.0), (u'tiny', -99.0), (u'homepart', 1.0), ('Country', 'Afghanistan'), ('Index', 104L), ('A2', 'AF'), ('A3', 'AFG'), ('Code', 4), ('1', nan), ('730', nan), ('1000', nan), ('1150', nan), ('1280', nan), ('1300', nan), ('1348', nan), ('1400', nan), ('1450', nan), ('1500', nan), ('1550', nan), ('1570', nan), ('1600', nan), ('1650', nan), ('1700', nan), ('1720', nan), ('1750', nan), ('1775', nan), ('1800', nan), ('1820', nan), ('1850', nan), ('1870', nan), ('1890', nan), ('1913', nan), ('1929', nan), ('1950', 644.7561631573), ('1960', 739.4106486121), ('1973', 684.0618506358), ('1980', 689.9746687251), ('1990', 604.0490304301), ('2000', 565.2309015098), ('2008', 868.8580032192)])

2 Answers 2


What are you trying to do ? Read carefully the documentation: The Fiona User Manual: what you want to do is well explained.

A schema is a Python dictionary, even if it is ordered:

import fiona
layer = fiona.open('shapefile.shp')
# copy the schema
newschema = layer.schema.copy()

If you want to add a new field (key of the dictionary)) to newschema, use the classic Python dictionary command:

newschema['properties']['newfield'] = float
# or
newschema['properties']['newfield'] = 'float:15.2'

And if you use with fiona.open('shapefile.shp', theclose()`is implicit at the end (you don't need it, look at Understanding Python's "with" statement :

"so to open a file, process its contents, and make sure to close it, you can simply do:"

with open("x.txt") as f:
   data = f.read()
   do something with data
  • Thanks for responding. Please look at my question again that was quite clear. I want to know add data to a shape file in fiona ideally using orderddictionary. This was not "well" explained well in the documentation and completely missing in your answer. Thank you for the advice on the close statement. Commented Mar 4, 2014 at 19:56
  • You can't, you've to create a new dictionary How can i add the element at the top of OrderedDict in python
    – gene
    Commented Mar 4, 2014 at 20:40
  • I did create a new dictionary called Kr from a list of ordereddictionarys (I have all the data joined already) see bottom of question. I just need to know where to go from that point. I feel like a am close but just don't have the syntax but I really don't know. Commented Mar 4, 2014 at 20:45
  • sorry, but but I don't understand your script. Where did gh[0] come from ? Why did-you use close() ?
    – gene
    Commented Mar 4, 2014 at 21:20
  • OK, gh is a big list of ordereddicts. I got it from a pandas (python library) merge. gh[0] is the first orderedict you can see it in bottom of my question - that is what kr and gh[0] look like. I need the new schema as I have new fields, that much worked. I am just trying to get that first ordereddict into my copied shape file with the new schema. I would like to do all of them but I just started with gh[0]. So I have a shape file. I got the data out, merged it, copied the original shapefile and added the new field schema. Commented Mar 5, 2014 at 0:04

OK looks like the next() function in fiona does not work with an empty - schema only file (at least on two of my linux computers). Therefore this can not be done in fiona at the present time by any method I can figure out as that is how data is appended in Fiona.

As a work around use geopandas. This is new so be careful. There just load shapefile into a GeoDataFram then do a join shapefile data and other data in a new DataFrame. You CANNOT just do a join to a GeoDataFrame write now. Once you have a nice dataframe ordered exactly like the GeoDataFrame 'append' the data from joined data 'normal' dataframe to the GeoDataFrame. You can do this by using a 'series' or a variety of data types see docs. I little bit of a work around but it works.

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.