在SDE数据库Python中识别不活动/未使用的域

时间:2018-09-11 02:32:27

标签: python arcgis-server

我一直在搜索工具/脚本论坛,以便能够识别sde数据库中正在使用的域和未使用的域。我遇到了一个py脚本工具,该工具非常适合.gdb,但在.sde上尝试时却不断出现错误。

# Add as 'Script' in toolbox.
# Set Parameters input_workspace as string, output_workspace as string
# --------------------------------------------------------------------------

# --------------------------------------------------------------------------
# Import required modules
#
import arcpy
import os

# --------------------------------------------------------------------------

# --------------------------------------------------------------------------

# Get Paramaters for Script Tool
input_workspace = arcpy.GetParameterAsText(0) # The geodatabase with domains you wish to summarize
output_workspace = arcpy.GetParameterAsText(1) # A new file geodatabase which will house the domain info

# Set overwrite output
arcpy.env.overwriteOutput = True

# List the domain objects
arcpy.AddMessage("Listing domains in the input workspace.")
dList = arcpy.da.ListDomains(input_workspace)

# Create the output workspace
arcpy.AddMessage("Setting up the output workspace.")
arcpy.CreateFileGDB_management(("\\").join(output_workspace.split("\\") 
[:-1]), output_workspace.split("\\")[-1])

# Create the necessary tables in the output workspace
arcpy.AddMessage("Creating tables.")
arcpy.AddMessage("\tDomain Properties table.")
arcpy.CreateTable_management(output_workspace,"domainProperties","#","#")
arcpy.AddMessage("\tRange Domain table.")
arcpy.CreateTable_management(output_workspace,"rangeDomains","#","#")
arcpy.AddMessage("\tApplied domains table.")
arcpy.CreateTable_management(output_workspace,"appliedDomains","#","#")
for d in dList:
if d.domainType == "CodedValue":
    arcpy.AddMessage("\t" + d.name + " CV info table.")
    arcpy.CreateTable_management(output_workspace,"cv_" + d.name + "_details","#","#")

# Add the necessary fields to the tables in the output workspace
arcpy.AddMessage("Adding fields.")
arcpy.AddMessage("\tDomain Properties table.")
arcpy.AddField_management(output_workspace + "\\domainProperties", "name", "TEXT")
arcpy.AddField_management(output_workspace + "\\domainProperties", "description", "TEXT")
arcpy.AddField_management(output_workspace + "\\domainProperties", "type", "TEXT")
arcpy.AddField_management(output_workspace + "\\domainProperties", "owner", TEXT")
arcpy.AddField_management(output_workspace + "\\domainProperties", "fieldType", "TEXT")
arcpy.AddField_management(output_workspace + "\\domainProperties", "applied", "TEXT")
arcpy.AddMessage("\tRange Domain table.")
arcpy.AddField_management(output_workspace + "\\rangeDomains", "name", "TEXT")
arcpy.AddField_management(output_workspace + "\\rangeDomains", "minValue", "DOUBLE")
arcpy.AddField_management(output_workspace + "\\rangeDomains", "maxValue", "DOUBLE")
arcpy.AddField_management(output_workspace + "\\rangeDomains", "fieldType", "TEXT")
arcpy.AddMessage("\tApplied domains table.")
arcpy.AddField_management(output_workspace + "\\appliedDomains", "featureClass", "TEXT")
arcpy.AddField_management(output_workspace + "\\appliedDomains", "field", "TEXT")
arcpy.AddField_management(output_workspace + "\\appliedDomains", "domainName", "TEXT")

arcpy.env.workspace = output_workspace
cvTables = arcpy.ListTables("cv_*")
for table in cvTables:
    arcpy.AddMessage("\t" + table)
    arcpy.AddField_management(output_workspace + "\\" + table, "code", "TEXT")
    arcpy.AddField_management(output_workspace + "\\" + table, "description", "TEXT")

# Populate the domain properties table
arcpy.AddMessage("Populating the domain properties table.")
table = output_workspace + "\\domainProperties"
fields = ["name", "description", "type", "owner", "fieldType"]
cursor = arcpy.da.InsertCursor(table, fields)
for d in dList:
    arcpy.AddMessage("\t" + d.name)
    name = d.name
    description = d.description
    dType = d.domainType
    owner = d.owner
    fieldType = d.type
    row = (name, description, dType, owner, fieldType)
    cursor.insertRow(row)

# Populate the range domains table
arcpy.AddMessage("Populating the range domains table.")
table = output_workspace + "\\rangeDomains"
fields = ["name", "minValue", "maxValue", "fieldType"]
cursor = arcpy.da.InsertCursor(table, fields)
for d in dList:
    if d.domainType == "Range":
        arcpy.AddMessage("\t" + d.name)
        name = d.name
        minValue = d.range[0]
        maxValue = d.range[1]
        fieldType = d.type
        row = (name, minValue, maxValue, fieldType)
        cursor.insertRow(row)

# Populate the coded value domain tables
arcpy.AddMessage("Populating the coded value domain tables.")
fields = ["code", "description"]
for d in dList:
    if d.domainType == "CodedValue":
        arcpy.AddMessage("\t" + d.name)
        table = output_workspace + "\\cv_" + d.name + "_details"
        cursor = arcpy.da.InsertCursor(table, fields)
        codedValues = d.codedValues
        for value in codedValues:
            code = value
            description = codedValues[code]
            row = (value, description)
            cursor.insertRow(row)

# Populate the applied domains table
arcpy.AddMessage("Populating the applied domains table.")
table = output_workspace + "\\appliedDomains"
fields = ["featureClass", "field", "domainName"]
cursor = arcpy.da.InsertCursor(table, fields)

# List the feature classes
fcs = []
walk = arcpy.da.Walk(input_workspace, datatype="FeatureClass")
for dirpath, dirnames, filenames in walk:
    for filename in filenames:
        fcs.append(os.path.join(dirpath, filename))

# Test to see if the fields have domains, and write the info to the applied 
domains table if they do
checked = 0
for fc in fcs:
    fieldList = arcpy.ListFields(fc)
    for field in fieldList:
        if field.domain != "":
            fcName = arcpy.Describe(fc).baseName
            fieldName = field.name
            domainName = field.domain
            row = (fcName, fieldName, domainName)
            cursor.insertRow(row)
    checked += 1
    if not checked % 50:
        arcpy.AddMessage("\tSuccessfully checked domains for " + str(checked) + " out of " + str(len(fcs)) + " feature classes.")

# Indicate which domains are applied in the geodatabase
arcpy.AddMessage("Indicating which domains are actually applied in the 
domain properties table.")
allDomains = []
uniqueDomains = []
table = output_workspace + "\\appliedDomains"
fields = ["domainName"]
with arcpy.da.SearchCursor(table, fields) as cursor:
    for row in cursor:
        allDomains.append(row[0])

for domain in set(allDomains):
    uniqueDomains.append(domain)

table = output_workspace + "\\domainProperties"
fields = ("name", "applied")
with arcpy.da.UpdateCursor(table, fields) as cursor:
    for row in cursor:
        if row[0] in uniqueDomains:
            row[1] = "Yes"
        else:
            row[1] = "No"
        cursor.updateRow(row)

del cursor, table, fields

在sde上尝试使用此工具时,我不断遇到的错误如下:

Failed script exportDomainProperties...

Traceback (most recent call last):
 File "D:\Downloads\exportDomainProperties\exportDomainProperties.py", line 55, in <module>
  arcpy.CreateTable_management(output_workspace,"cv_" + d.name + _details","#","#")
 File "c:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\management.py", line 15306, in CreateTable
  raise e
ExecuteError: ERROR 999999: Error executing function.
Failed to execute (CreateTable).

Failed to execute (exportDomainProperties).
Failed at Tue Sep 11 10:59:44 2018 (Elapsed Time: 1 minutes 0 seconds)

正如我所说的,它可以在.gdb上完美运行,并且domainProperties输出表正是我要用来标识正在使用和未使用的域的内容。我对PY一无所知,因此该脚本非常适合作为工具添加。请PYTHON脚本编写者帮我解决这个问题。

谢谢

1 个答案:

答案 0 :(得分:0)

我知道了,这与SDE无关。 SDE数据库具有一个名为No / Yes的域,并且由于字符/而引发错误,一旦将其删除,脚本将按预期运行。