Luke,<br><br>Please check if there are features with duplicate FIDs in the MSSQL datasource. The 'uniqueness' of the FIDs is not checked throughly in OGR. Some may slip through.<br><br>
Resetting the FIDs is not always desirable. Some applications might need to retain the old FIDs.<br>However, having an option to reset them could be useful in some cases. I am not sure if doing this in OGRDataSource::CopyLayer() is appropriate.<br>
<br><div class="gmail_quote">On Wed, Jul 6, 2011 at 8:41 PM, Luke Peterson <span dir="ltr"><<a href="mailto:luke.peterson@gmail.com">luke.peterson@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<br>
I'm reviving a nearly-year-old thread here, sort of. I'm trying to<br>
create cross-compatibility between MSSQL and PostGIS on some OGR-based<br>
code I wrote in Python for the MSSQL environment: I had been running<br>
into issues simply creating layers with OGR -- would run something<br>
like this:<br>
<br>
name = serverDS.CopyLayer(shapeDS.GetLayerByIndex(0),table,options).GetName()<br>
<br>
with serverDS being an open OGR datastore (destination) and shapeDS<br>
being an opened Shapefile (with an OGR-imposed FID).<br>
<br>
This code works fine when serverDS is a MSSQLSpatial driver, but I get<br>
hit with the following error when I run with a PostgresSQL driver:<br>
<br>
"You've inserted feature with an already set FID and that's perhaps<br>
the reason for the failure. If so, this can happen if you reuse the<br>
same feature object for sequential insertions. Indeed, since GDAL<br>
1.8.0, the FID of an inserted feature is got from the server, so it is<br>
not a good ideato reuse it afterwards... All in all, try unsetting the<br>
FID with SetFID(-1) before calling CreateFeature()"<br>
<br>
OK, clear enough. I took a look at the DataStore code here and here:<br>
<br>
<a href="http://trac.osgeo.org/gdal/browser/branches/1.8/gdal/ogr/ogrsf_frmts/pg/ogrpgdatasource.cpp" target="_blank">http://trac.osgeo.org/gdal/browser/branches/1.8/gdal/ogr/ogrsf_frmts/pg/ogrpgdatasource.cpp</a><br>
<br>
<a href="http://trac.osgeo.org/gdal/browser/branches/1.8/gdal/ogr/ogrsf_frmts/generic/ogrdatasource.cpp" target="_blank">http://trac.osgeo.org/gdal/browser/branches/1.8/gdal/ogr/ogrsf_frmts/generic/ogrdatasource.cpp</a><br>
<br>
I noticed that the PG driver has no PG-native code for CopyLayer() at<br>
all; the generic driver's CopyLayer() function doesn't set a null FID<br>
for CreateFeature(). So, it seems CopyLayer() is useless for PostGIS<br>
in my situation.<br>
<br>
The code I'm going with right now uses CopyLayer() out of the box<br>
except if serverDS.GetDriver().GetName() == 'PostgreSQL', in which<br>
case I'm re-implementing most of the logic from CopyLayer() in Python<br>
except adding a SetFID(-1) call:<br>
<br>
newLayer =<br>
serverDS.CreateLayer(table,shapeDS.GetLayerByIndex(0).GetSpatialRef(),ogr.wkbUnknown,options)<br>
for x in<br>
xrange(shapeDS.GetLayerByIndex(0).GetLayerDefn().GetFieldCount()):<br>
newLayer.CreateField(shapeDS.GetLayerByIndex(0).GetLayerDefn().GetFieldDefn(x))<br>
<br>
newLayer.StartTransaction()<br>
for x in xrange(shapeDS.GetLayerByIndex(0).GetFeatureCount()):<br>
newFeature = shapeDS.GetLayerByIndex(0).GetFeature(x)<br>
newFeature.SetFID(-1)<br>
newLayer.CreateFeature(newFeature)<br>
if x % 128 == 0:<br>
newLayer.CommitTransaction()<br>
newLayer.StartTransaction()<br>
newLayer.CommitTransaction()<br>
<br>
So I guess my question is whether I'm missing something, or whether I<br>
should submit a bug report or feature request on the PG driver to<br>
create a parallel implementation for CopyLayer() that either natively<br>
incorporates the SetFID(-1) or that takes an option that could trigger<br>
that behavior. Seems a shame this function exists but doesn't work<br>
under certain circumstances (again -- maybe I'm missing something?)<br>
<br>
Regards,<br>
Luke<br>
<br></blockquote></div>-- <br>Best regards,<br>Chaitanya kumar CH.<br>/tʃaɪθənjə/ /kʊmɑr/ <br>+91-9494447584<br>17.2416N 80.1426E<br>