2

when using the SQLite driver in python - setting a feature after changing an attribute field value creates an infinite loop on the first record. the same code works fine if i substitute the sqlite driver for an esri shapefile. some code to setup the issue -

'''create a new database with a point feature containing 2 records'''
def mkptdb():
    drv=ogr.GetDriverByName('SQLite')
    if os.path.exists('test.sqlite'):
        os.remove('test.sqlite')
    ds=drv.CreateDataSource('test.sqlite',options=['SPATIALITE=yes'])
    lyr=ds.CreateLayer('test',None,ogr.wkbPoint25D)
    flddef=ogr.FieldDefn('Name',ogr.OFTString)
    flddef.SetWidth(32)
    lyr.CreateField(flddef)
    flddef=ogr.FieldDefn('newfld',ogr.OFTString)
    flddef.SetWidth(32)
    lyr.CreateField(flddef)

    feat=ogr.Feature(lyr.GetLayerDefn())
    feat.SetField('Name','george')
    pt=ogr.Geometry(ogr.wkbPoint)
    pt.AddPoint(150000,48375999)
    feat.SetGeometry(pt)
    lyr.CreateFeature(feat)

    feat=ogr.Feature(lyr.GetLayerDefn())
    feat.SetField('Name','fred')
    pt=ogr.Geometry(ogr.wkbPoint)
    pt.AddPoint(150050,48376005)
    feat.SetGeometry(pt)
    lyr.CreateFeature(feat)

    feat.Destroy()
    ds=None

'''function to update one of the existing fields - this is the part that loops forever'''
def updatePt():
    print 'updating...'
    drv=ogr.GetDriverByName('SQLite')
    ds=drv.Open('test.sqlite',True)
    lyr=ds.GetLayerByName('test')
    for feat in lyr:
        s=feat.GetField('name')
        print s
        feat.SetField('newfld','hi')
        lyr.SetFeature(feat) #continuous loop stops if this is commented out
        feat.Destroy()

as noted above - if i comment out the line 'lyr.SetFeature(feat)' - the infinite loop ends and the feature will increment as expected. but without that line, the field value is not updated.

thoughts? python 2.7.6, gdal 1.10.1 (just noticed there might be an update here to 1.11.05, will check.) EDIT: updated to gdal 1.11.0 - same issue of infinite loop.

1

perhaps not as much an answer as a workaround? not sure what is going on with GetNextFeature in conjunction with SetFeature - but it would not iterate as expected. (a bug?) the below workaround seems to do the trick - by first getting a list of all feature FID's - then using GetFeature() in a new loop.

def updatePt():
    print 'updating...'
    drv=ogr.GetDriverByName('SQLite')
    ds=drv.Open('test.sqlite',True)
    lyr=ds.GetLayerByName('test')
    id=[]
    for f in lyr:
        id.append(f.GetFID())
    for i in id:
        feat=lyr.GetFeature(i)
        feat.SetField('newfld','last1')
        lyr.SetFeature(feat)
        print feat.GetField('name'),feat.GetField('newfld')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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