[Qgis-developer] How to use QPyNullVariant() to "empty" primary key fields in spatialite layer

Alexandre Neto senhor.neto at gmail.com
Fri Aug 30 09:14:15 PDT 2013


Thank you for the fast repplies. Meanwhile I found out that spatialite does
not like polygons writen in a multipolygon table... And have been trying to
solve that.


Anyway, both None and QPyNullVariant(int) works, only if the splitted
feature has only two parts.


If  the result has two or more new features I get this error:


Could not commit changes to layer poligonos
> Errors: ERROR: 2 feature(s) not added.
> Provider errors:
> SQLite error: PRIMARY KEY must be unique
> SQL: INSERT INTO
> "poligonos"("geometria","pkuid","filed1","field2","filed3") VALUES
> (ST_Multi(GeomFromWKB(?, 4326)),?,?,?,?)


I fill function code is bellow.


Regards,


Alexandre


    def run(self):
>         layer = self.canvas.currentLayer()
>         provider = layer.dataProvider()
>         n_of_splitted_features = 0
>         n_of_new_features = 0
>         layer.beginEditCommand(QCoreApplication.translate('Multipart
> split','Split feature(s) parts'))
>         # Iterate over all selected feature to find multipart features
>         for feature in layer.selectedFeatures():
>             geom = feature.geometry()
>             # if feature geometry is multipart starts split processing
>             if geom != None:
>                 if geom.isMultipart():
>                     new_features = []
>                     n_of_splitted_features += 1
>                     temp_feature = QgsFeature()
>                     # Get attributes from original feature
>                     new_attributes = feature.attributes()
>
>                     # When attribute is a Primary Key, replace by default
> value
>                     ### This is not working well with spatialite
> provider###
>                     for j in provider.pkAttributeIndexes():
>                         if provider.defaultValue(j):
>                             new_attributes[j] = provider.defaultValue(j)
>                         else:
>                             new_attributes[j] = QPyNullVariant(int)
>
>                     temp_feature.setAttributes(new_attributes)
>
>                     # Get parts geometries from original feature
>                     parts = geom.asGeometryCollection ()
>
>                     # from 2nd to last part create a new features using
> their
>                     # single geometry and the attributes of the original
> feature
>
>                     # Convert part to multiType to prevent errors in
> Spatialite
>                     for part in parts:
>                         part.convertToMultiType()
>
>                     for i in range(1,len(parts)):
>                         n_of_new_features += 1
>                         temp_feature.setGeometry(parts[i])
>                         temp_feature.geometry().convertToMultiType()
>                         new_features.append(QgsFeature(temp_feature))
>                     # update feature geometry to hold first part single
> geometry
>                     # (this way one of the output features keeps the
> original Id)
>                     feature.setGeometry(parts[0])
>                     layer.updateFeature(feature)
>                     layer.addFeatures(new_features, False)



On Fri, Aug 30, 2013 at 10:48 AM, Nathan Woodrow <madmanwoo at gmail.com>wrote:

> Have you tried just setting it to None?
>
> - Nathan
>
>
> On Fri, Aug 30, 2013 at 7:38 PM, Alexandre Neto <senhor.neto at gmail.com>wrote:
>
>> In the multipartsplit plugin [1] I'm trying to solve the primary key (pk)
>> fields problem in postgis and spatialite like in it was done in the
>> splitFeatures() [2]
>>
>> I have no problems with Postgis provider, but in spatialite setting pk
>> fields to NULL does not work as I expected, and spatialite does not choose
>> a new non used id by it self. (Making it impossible to commit the changes
>> without manually introduce some id)
>>
>> In splitFeatures() [2] when a field is in provider.pkAttributeIndexes<http://www.qgis.org/api/classQgsVectorDataProvider.html#a6e19d018aa0b88da21fdb9d02c5e8a60>(),
>> but has no default value, the filed is set to empty with this
>>
>>
>> newAttributes[ pkIdx ] = QVariant();
>>
>>
>> But i'm not being able to use it in my code, since it's says QVariant()
>> can not be instantiated. Actually this is said in here [3]. And it says
>> that Null QVariant() are now converted in QPyNullVariant
>>
>> Can I use QPyNullVariant to keep the pk field empty, so that
>> spatialite automatically choose a adequate int value? How?
>>
>> I tried the code bellow but it did not work.
>>
>> # Get attributes from original feature
>>> new_attributes = feature.attributes()
>>>
>>
>>
>>> # When attribute is a Primary Key, replace by provider default value
>>
>>
>>
>>> for j in provider.pkAttributeIndexes():
>>>     if provider.defaultValue(j):
>>>         new_attributes[j] = provider.defaultValue(j)
>>>     else:
>>>         new_attributes[j] = QPyNullVariant('int')
>>
>>
>>
>> Thanks.
>>
>> Alexandre Neto
>>
>> [1] http://plugins.qgis.org/plugins/splitmultipart/
>> [2]
>> http://www.qgis.org/api/qgsvectorlayereditutils_8cpp_source.html#l00247
>> [3]
>> http://hub.qgis.org/wiki/quantum-gis/Python_plugin_API_changes_from_18_to_20
>>
>>
>>
>> _______________________________________________
>> Qgis-developer mailing list
>> Qgis-developer at lists.osgeo.org
>> http://lists.osgeo.org/mailman/listinfo/qgis-developer
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20130830/5332e898/attachment.html>


More information about the Qgis-developer mailing list