4

This resource shows how to use NULL values in pyqgis. Within the python colsole the comparison value == NULL passes without exception. However, when run from my plugin NULL is neither in the global nor the local namespace

NameError: global name 'NULL' is not defined

The only way to check for NULL values seems to be to check for an instance of QPyNullVariant

from PyQt4.QtCore import QPyNullVariant
if isinstance(value, QPyNullVariant):
    pass 

How do I import NULL so I can compare value == NULL?

EDIT

For those wondering why and how NULL is different from None have a look at this blog entry. Essentially historically is wasn't possible to return None:

Turns out by removing QVariant from PyQt it had some impact on methods that expected a NULL QVariant - A QVariant with no value. Passing None didn't work because those methods needed the type information that QVariant holds, even when NULL.

On None comparisons it says:

One way to check if something is Null in Python is to use value is None however this will not work with our NULL type. Overloading the is operator in Python is not supported and there is no way we can support this - trust me I have tried. is is really doing id(object) == id(object) under the hood:

8

NULL is defined in qgis.core

import qgis.core
if f["SAMPLE"] == qgis.core.NULL:
   ...

Normally you should be able to do a normal is None check however due to tool we use to generate the Python API it will convert null values on the C++ side (which is what QGIS is written in) to QPyNullVariant. We tried to talk the PyQt devs around to making it just return None but didn't have much luck.

  • Thanks for your answer, this was what I was looking for. I also have edited my question to provide more information on the topic. – LarsVegas Oct 31 '16 at 11:13
  • Good answer. Minor sidenote None is used for invalid attributes (e.g. were not specified in setSubsetOfAttributes) so NULL was left there on purpose and the two should not be confused. – Matthias Kuhn Oct 31 '16 at 14:45
-3

You don't need a NULL value in Python:

value = ""
if value:
   print value
...
if not(value):
   print('ok')
ok
value = None
if value == None:
   print("ok")
ok
if not(value):
   print("ok")
ok

In the example cited

lyrPth = "/qgis_data/shapes/NullExample.shp"
lyr = QgsVectorLayer(lyrPth, "Null Field Example", "ogr")
features = lyr.getFeatures()
f = features.next()
value = f["SAMPLE"]
value == None
True
if  not(value): print("True")
True

New

With OGR is is the same thing

from osgeo import ogr
reader = ogr.Open("NullExample.shp")
layer = reader.GetLayer()
# first feature
feature = layer.GetFeature(0)
import json
geojson = json.loads(feature.ExportToJson())
geojson['properties']['SAMPLE']==None
True
if  not(geojson['properties']['SAMPLE']):print("True")
True

With Fiona

import fiona
shape = fiona.open("NullExample.shp")
first = shape.next()
first['properties']['SAMPLE'] == None
True
  • You will need qgis.core.NULL which is really just a typedef for QPyNullVariant. What we use to generate the Python API for QGIS doesn't convert values to None it converts them to QPyNullVariant. Long story. – Nathan W Oct 31 '16 at 11:01
  • 1
    Getting a layer by lyr.getFeatures(QgsFeatureRequest(feature_id)).next() is totally different than reading in shape file with ogr – LarsVegas Oct 31 '16 at 11:31
  • I am sorry, but it is the same think, look at New – gene Oct 31 '16 at 13:08
  • 1
    value is None only works for real None values. NULL was made to look very similar to None (because mostly it helps to avoid annoying mistakes) but in it's core it's different. – Matthias Kuhn Oct 31 '16 at 18:14

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.