Select to view content in your preferred language

Setting Field Properties to Not Nullable

2411
9
03-19-2014 08:43 AM
benberman
Regular Contributor
I have a simple script that I think would automate this task, it runs but I dont see any changes in the field properties...

>>> fieldList = arcpy.ListFields(path to the feature class)
>>> for field in fieldList:
...     field.isNullable = False

any ideas?
Tags (2)
0 Kudos
9 Replies
Zeke
by
Honored Contributor
This may be a read only property that you can only set when creating the field.
0 Kudos
JoshuaChisholm
Frequent Contributor
Hello FLBB,

Bad news;
"Updating a field property only updates the field object, no changes are made to the actual field in the table or feature class." (-ESRI Documentation)

As a poor workaround, you can try create new fields, calculate the over the values and then delete the original fields (see similar posting).

Good luck!
0 Kudos
benberman
Regular Contributor
I would expect that there may be some type of override. I can accomplish this task in Diagrammer but I want to start automating to save time.
0 Kudos
JoshuaChisholm
Frequent Contributor
Hello FLBB,

I think changing the field properties is often forbidden because it is very easy to corrupt the data. I can't find any way to permanently change the is nullable property of a field in ArcMap or arcpy.

I'm not sure why ESRI even allowed this property to be writable since it doesn't get saved anywhere.

Most solutions I run into seem to suggest creating a new field, transferring the data and then deleting the old one.
0 Kudos
benberman
Regular Contributor
Actually, I was able to accomplish this task by using the python XML package:

from xml.etree import ElementTree as et
tree = et.parse(xmlfilename)
tree.find('.//IsNullable').text = 'false'
tree.write(xmlfilename)

Basically any element or "tag" value in an already built schema may be changed using a similar format.

Next, what I would like to accomplish is, instead of specifying each XML file individually, I want for the script to be able to automatically call all XML documents within a folder and complete this task. If anyone has any ideas it'd be much appreciated.
0 Kudos
JoshuaChisholm
Frequent Contributor
Nice solution FLBB! Does it work when you open that file in ArcMap?

This should find all xml documents in a given directory.
import os
for aFile in os.listdir(r"C:\Path\To\Data"):
    if aFile.lower().endswith(".xml"):
        print aFile
        #Do stuff to xml files
0 Kudos
benberman
Regular Contributor
Nice solution FLBB! Does it work when you open that file in ArcMap?

This should find all xml documents in a given directory.
import os
for aFile in os.listdir(r"C:\Path\To\Data"):
    if aFile.lower().endswith(".xml"):
        print aFile
        #Do stuff to xml files


This code above simply lists the XML files. I am thinking something more along the lines of:

>>> from xml.etree import ElementTree as et
... import os
... workspace = r"C:\test"
... for dirpath, dirnames, filenames in os.walk(workspace):
...     for filename in filenames:
...         if '.xml' in filename:
...             tree = et.parse(os.path.join(dirpath, filename))
...             tree.find('.//IsNullable').text = 'false'
...             tree.write(os.path.join(dirpath,filename))
...            
Runtime error
Traceback (most recent call last):
  File "<string>", line 8, in <module>
AttributeError: 'NoneType' object has no attribute 'text'

Obviously I'm missing a piece to this. Any help would be greatly appreciated.
0 Kudos
JoshuaChisholm
Frequent Contributor
Hello FLBB,

I changed you if statement. This one will skip files like about.xmlfiles.txt (which is possible). It will also be case insensitive (accepting both '.xml' and '.XML' files).

I think you also need an if statement to see if 'IsNullable' actually appears in the xml file.

from xml.etree import ElementTree as et
import os
workspace = r"C:\test"
for dirpath, dirnames, filenames in os.walk(workspace):
    for filename in filenames:
        if filename.lower().endswith('.xml'):
            tree = et.parse(os.path.join(dirpath, filename))
            targetTag=tree.find('.//IsNullable')
            if targetTag is not None:
                targetTag.text = 'false'
            else:
                print "No IsNullable tag was NOT found in: "+filename
            tree.write(os.path.join(dirpath,filename))


I not 100% confident this methodology will actually change the Nullable field property. I worried that you are only changing the metadata and the actual field property (in the '.dbf') is not changing. Can you actually put null values into a field of one of the shapefiles you have modified?

Let be know how it goes!
0 Kudos
benberman
Regular Contributor
Hello FLBB,

I changed you if statement. This one will skip files like about.xmlfiles.txt (which is possible). It will also be case insensitive (accepting both '.xml' and '.XML' files).

I think you also need an if statement to see if 'IsNullable' actually appears in the xml file.

from xml.etree import ElementTree as et
import os
workspace = r"C:\test"
for dirpath, dirnames, filenames in os.walk(workspace):
    for filename in filenames:
        if filename.lower().endswith('.xml'):
            tree = et.parse(os.path.join(dirpath, filename))
            targetTag=tree.find('.//IsNullable')
            if targetTag is not None:
                targetTag.text = 'false'
            else:
                print "No IsNullable tag was NOT found in: "+filename
            tree.write(os.path.join(dirpath,filename))


I not 100% confident this methodology will actually change the Nullable field property. I worried that you are only changing the metadata and the actual field property (in the '.dbf') is not changing. Can you actually put null values into a field of one of the shapefiles you have modified?

Let be know how it goes!


Sorry I am a little late responding to this, thank you very much for your assistance, Josh.  Yes, it is confirmed that both of our methods do work and yes, it is confirmed that this method will in fact set the "Allow Null Values" property in the GDB schema.
0 Kudos