Python for checking field length?

896
5
02-27-2020 09:51 AM
AllenDailey1
Occasional Contributor

I am trying to find an efficient way to check the maximum possible field length for many feature classes that are in datasets in an enterprise database system.  The problem I'm seeking to solve is that once in a while, a field within a feature class has a field length limit of over a billion characters. The actual data within the field is less than 255 characters, though. So I want to find the long fields and then I will edit the max length to 255.

I would love to use Python / arcpy to find the long fields. I have taken a class in Python but am not an expert, and I am brand new to using it in ArcGIS, so it would be great if you could explain things accordingly.    thank you!!

Here is the code I have so far.

It does begin with import arcpy - I forgot to include that in the screenshot.

Here it is in a form where you can copy and paste if you want to try it out with your own workspace:

import arcpy

arcpy.env.workspace = r'Database Connections\prvgisdb1-GIS-webadmin.sde'
data_sets = arcpy.ListDatasets()
for data_set in data_sets:
    print data_set # Datasets printed!
    FCs = arcpy.ListFeatureClasses(data_set)
    for FC in FCs:
        print(FC) # Feature classes did NOT print.
        fields = arcpy.ListFields(FC)
        for field in fields:
            if field.length > 255:
            print("{0} {1} {2}".format(field.name, field.type, field.length)) #Fields did NOT print.

It successfully connects to the database and prints the names of the datasets (this printing is for testing purposes).  However, nothing else printed.

I know the last half of the code does work, though - I have successfully gotten the long fields to print when I told it which feature class to look at. And there are indeed fields over 255 characters, so something should print.

Apparently there is some problem in this code where I have tried to put all the pieces together.

Any suggestions?

Thank you!!

0 Kudos
5 Replies
DavidPike
MVP Frequent Contributor
import arcpy
import os

sde_path = r'Database Connections\prvgisdb1-GIS-webadmin.sde'
arcpy.env.workspace = sde_path

datasets = arcpy.ListDatasets()

dataset_path_list = []
for dataset_name in datasets:
    dataset_path = os.path.join(sde_path, dataset_name)
    dataset_path_list.append(dataset_path)

all_fc_path_list = []    
for dataset_path in dataset_path_list:
    feature_classes = arcpy.ListFeatureClasses(dataset_path)
    for fc in feature_classes:
        fc_path = os.path.join(dataset_path, fc)
        all_fc_path_list.append(fc_path)

for fc in all_fc_path_list:        
    fields = arcpy.ListFields(FC)
    #for field in fields: ##### 

##### have a look at this link to finish it off. i hate field mappings
##### https://community.esri.com/thread/159184



        
AllenDailey1
Occasional Contributor

EDIT: SEE MY NEWEST REPLY farther down in the discussion - I went with a different approach and got something to work!!

Hi David,

Thank you so much for sharing this code with me!  I really appreciate it.  I can see how it makes sense.

I tried it out, but it did not work for me - nothing printed.

I've been working on making adjustments and trying slightly different approaches, but I have not found a solution.  I printed the dataset path along the way and found that the "r" was not part of it, so I was wondering if I should add the "r" back in (In previous versions of my code, I discovered that the "r" is really necessary).

Below is my current version.  The dataset paths are formed correctly, as far as I can tell.  But feature classes within the datasets are never actually listed.  There seems to be a problem with "looking inside" the datasets.

Does anybody out there have any tips?

import arcpy
import os

sde_path = r'Database Connections\prvgisdb1-GIS-webadmin.sde'
arcpy.env.workspace = sde_path

datasets = arcpy.ListDatasets()

dataset_path_list = []
for dataset_name in datasets:
    dataset_path = os.path.join(sde_path, dataset_name)
    dataset_path_list.append(dataset_path)

read_ds_path_list = []
all_fc_path_list = []    
for ds_path in dataset_path_list: # For each dataset path,
    read_ds_path = "r'" + ds_path + "'" # Add "r" to it
    read_ds_path_list.append(read_ds_path) # Then add it to a different list
for rdp in read_ds_path_list: # For each dataset path in that list,
    print rdp #test - this works
    arcpy.env.workspace = rdp # Make it the workspace
    fcs = arcpy.ListFeatureClasses() # List the fc's in that workspace/dataset.
    print fcs # This does not work - prints "None" for each dataset.‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

Allen, it is easier to format the code so that there are line numbers as well as David has shown...

/blogs/dan_patterson/2016/08/14/script-formatting 

and the last line is not properly indented which could be a copy/paste issue

0 Kudos
AllenDailey1
Occasional Contributor

Dan, Thank you for the info about formatting code! I would have never found that on my own. 

Yeah, the incorrect indentation of the last line turned out to be a copy/paste problem.

Thanks!

0 Kudos
AllenDailey1
Occasional Contributor

Update:  I got it to work!  I found the Walk function and was able to use it to reach my goal of listing the fields and their lengths.  Thank you so much for your replies, David and Dan!

import arcpy
import os

workspace = r'Database Connections\prvgisdb1-GIS-webadmin.sde'
feature_classes = []

walk = arcpy.da.Walk(workspace, datatype="FeatureClass")

for dirpath, dirnames, filenames in walk:
    for filename in filenames:
        feature_classes.append(os.path.join(dirpath, filename))

for feature_class in feature_classes:
    fields = arcpy.ListFields(feature_class)
    for field in fields:
        if field.length > 255:
            print feature_class
            print("{0} {1} {2}".format(field.name, field.type, field.length))

-- Allen