Opened 11 years ago

Closed 11 years ago

#4148 closed defect (invalid)

add "PRESERVE_FID" option to CopyLayer()

Reported by: LWP Owned by: warmerdam
Priority: normal Milestone:
Component: OGR_SF Version: svn-trunk
Severity: normal Keywords: CopyLayer()


CopyLayer() is unusable in certain use cases for several OGR drivers including PG:

CopyLayer() requires a "PRESERVE_FID" option to mirror the functionality of ogr2ogr, in which the user may specify that the source FID be preserved (default behavior = FID is reset upon copy). The current implementation (in which the FID is always preserved) causes a collision issue that makes CopyLayer() unusable for the PostgresSQL driver in many situations.

Here's the write-up from gdal-dev@…:

I'm reviving a nearly-year-old thread here, sort of. I'm trying to create cross-compatibility between MSSQL and PostGIS on some OGR-based code I wrote in Python for the MSSQL environment: I had been running into issues simply creating layers with OGR -- would run something like this:

name = serverDS.CopyLayer(shapeDS.GetLayerByIndex(0),table,options).GetName()

with serverDS being an open OGR datastore (destination) and shapeDS being an opened Shapefile (with an OGR-imposed FID).

This code works fine when serverDS is a MSSQLSpatial driver, but I get hit with the following error when I run with a PostgresSQL driver:

"You've inserted feature with an already set FID and that's perhaps the reason for the failure. If so, this can happen if you reuse the same feature object for sequential insertions. Indeed, since GDAL 1.8.0, the FID of an inserted feature is got from the server, so it is not a good ideato reuse it afterwards... All in all, try unsetting the FID with SetFID(-1) before calling CreateFeature()"

OK, clear enough. I took a look at the DataStore code here and here: pgdatasource.cpp c/ogrdatasource.cpp

I noticed that the PG driver has no PG-native code for CopyLayer() at all; the generic driver's CopyLayer() function doesn't set a null FID for CreateFeature(). So, it seems CopyLayer() is useless for PostGIS in my situation.

yes indeed, CopyLayer() isn't currently appropriate for your use case. It does currently a poDstFeature.SetFID(poSrcFeature.GetFID()), which is the equivalent of the -preserve_fid option of ogr2ogr. In the append use case, this is not desirable because you will get collisions with features already inserted with the FID. The solution will be easy to implement and consists in adding an option "PRESERVE_FID" to CopyLayer(). No need to create a specialized implementation for the PG driver, that issue could be found in other drivers that can use the FID of features set to CreateFeature(). Please file a ticket about that.

Change History (1)

comment:1 by Even Rouault, 11 years ago

Resolution: invalid
Status: newclosed

Actually there's no need for such an option. See

Note: See TracTickets for help on using tickets.