| Message |
In both ArcGIS 9.1 and 9.2, if you create the geoprocessor through win32com (the "old" way of doing it), you can set nullable database field to NULL by setting is value to a Python None. But in 9.2, if you create the geoprocessor by importing the arcgisscripting Python module, you get an error. Does anyone know how to set a field to NULL with arcgisscripting?
The example code below shows what I'm talking about. I executed these from PythonWin. The first block simply creates a table with a nullable field and inserts a row with the value 12345. The second block shows that the field may be set to NULL by passing None to cur.SetValue, using the geoprocessor created with COM automation. The third block shows that when the geoprocessor is created with arcgisscripting, the NULL value may be read from the field (it is returned as Python None), and the value 12345 may be written to the field, but that Python None may not be written to the field.
Incidentally, I discovered that the update cursor object returned by the arcgisscripting geoprocessor has two undocumented functions:
IsNull - this appears to return 1 if a given field value is NULL and 0 if it is not NULL.
SetNull - I thought this was what I should use, but I cannot get it to work. It appears that you should be able to pass the field name and it would set the field to NULL, but as you can see in the third example, it doesn't work.
Anyone have any ideas? I believe this is a bug in 9.2 but I wanted to check with folks before I submitted a bug. I am running 9.2 SP4.
Best regards,
Jason |
| |
Code block #1: creates the table with a nullable field:
>>> import arcgisscripting
>>> gp = arcgisscripting.create()
>>> gp.CreatePersonalGDB_management('c:\\temp4', 'TestGDB.mdb')
'c:\\temp4\\TestGDB.mdb'
>>> gp.CreateTable_management('c:\\temp4\\TestGDB.mdb', 'TestTable')
'c:\\temp4\\TestGDB.mdb\\TestTable'
>>> gp.AddField_management('c:\\temp4\\TestGDB.mdb\\TestTable', 'MyField', 'LONG', '#', '#', '#', '#', 'NULLABLE')
'c:\\temp4\\TestGDB.mdb\\TestTable'
>>> cur = gp.InsertCursor('c:\\temp4\\TestGDB.mdb\\TestTable')
>>> row = cur.NewRow()
>>> row.SetValue('MyField', 12345)
>>> cur.InsertRow(row)
>>> del cur
Code block #2: shows that NULL can be written to the field if the geoprocessor is created with COM automation:
>>> import win32com.client
>>> gp = win32com.client.Dispatch('esriGeoprocessing.GPDispatch')
>>> cur = gp.UpdateCursor('c:\\temp4\\TestGDB.mdb\\TestTable')
>>> row = cur.Next()
>>> row.GetValue('MyField')
12345
>>> row.SetValue('MyField', None)
>>> cur.UpdateRow(row)
>>> del cur
Code block #3: shows that, if arcgisscripting is used, NULL can be read but not written:
>>> import arcgisscripting
>>> gp = arcgisscripting.create()
>>> cur = gp.UpdateCursor('c:\\temp4\\TestGDB.mdb\\TestTable')
>>> row = cur.Next()
>>> row.GetValue('MyField') # Returns None, which PythonWin indicates by displaying nothing
>>> row.SetValue('MyField', 12345)
>>> cur.UpdateRow(row)
>>> del cur
>>> cur = gp.UpdateCursor('c:\\temp4\\TestGDB.mdb\\TestTable')
>>> row = cur.Next()
>>> row.GetValue('MyField')
12345
>>> row.SetValue('MyField', None)
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
ValueError: invalid input value
>>> row.MyField = None
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
ValueError: invalid input value
>>> row.IsNull('MyField')
0
>>> row.SetNull('MyField')
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
RuntimeError: Error in executing function
|