table to domain: iterate through each file geodatabase

3955
9
10-26-2011 11:17 AM
PeterWilson
Occasional Contributor III
I need to add an attribute domain to multiple file geodatabases, using the geprocessing tool "table to domain" for each file geodatabase wihtin a directory within subfolders. I've attached a print screen of the folder structure. Any assistance in being able to achieve this will be appreciated. Please note that I have very little experience in python.

Regards
Tags (2)
0 Kudos
9 Replies
JakeSkinner
Esri Esteemed Contributor
Hi Peter,

It may be easiest to do this using a python script rather than model builder.  Here is an example on how to do this.  The below script will iterate through each sub directory in your 'H:\Projects\H107039_PeterW\workpackages' workspace:

import arcpy, os
from arcpy import env

folder = r"H:\Projects\H107039_PeterW\workpackages"

for (path, dirs, files) in os.walk(folder):
    if ".gdb" not in path.lower():
            env.workspace = path
            databases = arcpy.ListWorkspaces("*", "FileGDB")
            for database in databases:
                arcpy.TableToDomain_management(r"C:\TEMP\Python\domain.dbf", "Code", "Desc", database, "City")


You will just need to update the line "arcpy.TableToDomain_management(r"C:\TEMP\Python\domain.dbf", "Code", "Desc", database[0], "City")".  The first variable is the path to the table containing the domain.  The second variable is the field containing the domain code.  Third variable is the field containing the domain description, and the 5th variable is what you would like to name the domain.
0 Kudos
PeterWilson
Occasional Contributor III
Hi Peter,

It may be easiest to do this using a python script rather than model builder.  Here is an example on how to do this.  The below script will iterate through each sub directory in your 'H:\Projects\H107039_PeterW\workpackages' workspace:

import arcpy, os
from arcpy import env

folder = r"H:\Projects\H107039_PeterW\workpackages"

for (path, dirs, files) in os.walk(folder):
    if ".gdb" not in path.lower():
            env.workspace = path
            databases = arcpy.ListWorkspaces("*", "FileGDB")
            for database in databases:
                arcpy.TableToDomain_management(r"C:\TEMP\Python\domain.dbf", "Code", "Desc", database, "City")


You will just need to update the line "arcpy.TableToDomain_management(r"C:\TEMP\Python\domain.dbf", "Code", "Desc", database[0], "City")".  The first variable is the path to the table containing the domain.  The second variable is the field containing the domain code.  Third variable is the field containing the domain description, and the 5th variable is what you would like to name the domain.


I ran the script and received the following error:

Traceback (most recent call last):
  File "S:\Projects\H107039\GIS\ModelBuilder\TableToDomain2.py", line 10, in <module>
    arcpy.TableToDomain_management(r"S:\Projects\H107039\GIS\Domains.gdb\Landuse_Description", "Code", "Description", database[0], "Landuse Description", "Aurecon Landuse Description", "REPLACE")
IndexError: list index out of range

Here's the current structure of my script:

import arcpy, os
from arcpy import env

folder = r"S:\Projects\H107039\GIS\ModelBuilder\Geodatabases"

for (path, dirs, files) in os.walk(folder):
    if ".gdb" not in path.lower():
            env.workspace = path
            database = arcpy.ListWorkspaces("*", "FileGDB")
            arcpy.TableToDomain_management(r"S:\Projects\H107039\GIS\Domains.gdb\Landuse_Description", "Code", "Description", database[0], "Landuse Description", "Aurecon Landuse Description", "REPLACE")

Regards
0 Kudos
JakeSkinner
Esri Esteemed Contributor
That was my mistake.  I made an error in the code and updated it afterwards.  Try the following:

import arcpy, os
from arcpy import env

folder = r"S:\Projects\H107039\GIS\ModelBuilder\Geodatabases"

for (path, dirs, files) in os.walk(folder):
if ".gdb" not in path.lower():
    env.workspace = path
    databases = arcpy.ListWorkspaces("*", "FileGDB")
    for database in databases:
        arcpy.TableToDomain_management(r"S:\Projects\H107039\GIS\Domains.gdb\Landuse_Description", "Code", "Description", database, "Landuse Description", "Aurecon Landuse Description", "REPLACE")
0 Kudos
PeterWilson
Occasional Contributor III
Thank you so much for you assistance with the following. Would you mind explaining the reason that it never worked in order for me to learn from the current script so that I could use it for looping through other tools within ArcGIS? Thanks once again for your assistance.

Regards
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Sure, no problem.  Previously I had the following lines of code:

database = arcpy.ListWorkspaces("*", "FileGDB")
arcpy.TableToDomain_management(r"S:\Projects\H107039\GIS\Domains.gdb\Landuse_Description", "Code", "Description", database[0], "Landuse Description", "Aurecon Landuse Description", "REPLACE")


Whenever you use an 'arcpy.List....' function, python will return a list of values.  To select an individual value from the list you need to specify an index value.  That is where 'database[0]' comes into play.  The first value in the list begins with index 0, second value index 1, etc.  The code above simply specifies the first geodatabase in a directory, but there could be multiple geodatabase (probably why you received the error message). 

Therefore I changed the code to loop through each database in the list:

databases = arcpy.ListWorkspaces("*", "FileGDB")
for database in databases:
    arcpy.TableToDomain_management(r"S:\Projects\H107039\GIS\Domains.gdb\Landuse_Description", "Code", "Description", database, "Landuse Description", "Aurecon Landuse Description", "REPLACE")


The above code will now loop through every database in each sub directory rather than just finding the first one.

If you're interested in learning python I highly recommend the course Introduction to Geoprocessing Scripts Using Python.
0 Kudos
PeterWilson
Occasional Contributor III
Thank You so much, I will definitetly look into taking the course and purchasing a python reference book. You have just saved me hours in work time on my current project.

Regards
0 Kudos
PeterWilson
Occasional Contributor III
I'm trying to add the python script to an ArcToolBox and have adjusted the model to preset certain paramaters as they won't change. My current script is structured as follows:

import arcpy, os
from arcpy import env

folder = r"S:\Projects\H107039\GIS\ModelBuilder\Geodatabases"

for (path, dirs, files) in os.walk(folder):
    if ".gdb" not in path.lower():
        env.workspace = path
        databases = arcpy.ListWorkspaces("*", "FileGDB")
        Code = 'Code'
        Description = 'Description'
        Replace = 'REPLACE'
        for database in databases:
            arcpy.TableToDomain_management(r"S:\Projects\H107039\GIS\Domains.gdb\Landuse_Description",
                                               Code, Description, database, "Landuse Description",
                                               "Aurecon Landuse Description", Replace)

The only parameters that need to be defined by the end user are:

1) table containing domain
2) The name to be given to the domain
3) The description of the domain

I've set the parameters as follows when adding a script to the toolbox:

1) Table View (Input)
2) String (Input)
3) String (Input)

If I run the script within python it adds the additional domain to each file geodatabase. If I try to run the script from within Arctoolbox, its runs, completes, but nun of the file geodatabases are updated with the new domain.

Regards
0 Kudos
JakeSkinner
Esri Esteemed Contributor
When creating parameters for a script, you need to specify the 'arcpy.GetParameterAsText' function so python knows what inputs/variables to replace.  Try the following script:

import arcpy, os
from arcpy import env

folder = r"S:\Projects\H107039\GIS\ModelBuilder\Geodatabases"

for (path, dirs, files) in os.walk(folder):
    if ".gdb" not in path.lower():
        env.workspace = path
        databases = arcpy.ListWorkspaces("*", "FileGDB")
        Code = 'Code'
        Description = 'Desc'
        Replace = 'REPLACE'
        for database in databases:
            arcpy.TableToDomain_management(arcpy.GetParameterAsText(0), Code, Description, database, arcpy.GetParameterAsText(1), arcpy.GetParameterAsText(2), Replace)


The parameter data types you have setup within toolbox will be fine and you will not need to update these.  Also, when posting code it's good to wrap CODE tags (the '#' tool) the text so that it preserves indentation.
0 Kudos
PeterWilson
Occasional Contributor III
Thanks so much, here's my final script. Please if you wouldn't mind let me know where I should change the structure, layout or add notes to my script to learn to write my scripts correctly. I can't thank you enough for all the assistance that you have provided me today. I now feel that I really can learn how to write custom scripts with a lot more work of course, but I've now at least made a start.

import arcpy, os
from arcpy import env

folder = r"S:\Projects\H107039\GIS\ModelBuilder\Geodatabases"

for (path, dirs, files) in os.walk(folder):
    if ".gdb" not in path.lower():
        env.workspace = path
        databases = arcpy.ListWorkspaces("*", "FileGDB")
        # Set parameters
        DomainTable = arcpy.GetParameterAsText(0)
        Code = 'Code'
        Description = 'Description'
        DomainName = arcpy.GetParameterAsText(1)
        DomainDesc = arcpy.GetParameterAsText(2)
        Replace = 'Replace'
        # Run Tool
        for database in databases:
            arcpy.TableToDomain_management(DomainTable, Code, Description, database,
                                           DomainName, DomainDesc, Replace)


Regards
0 Kudos