Geoprocessing service related table output

676
2
02-16-2019 10:12 AM
GrantHaynes
Occasional Contributor

Hi Everyone,

I'm working on a project where I use a custom python toolbox tool as a geoprocessing service in web app builder.

The goal is a GP service that accepts a point feature class, drawn by the person using the web app, then extracts values at that point and builds a table of that data to be related to an output feature class which is charted by the related table chart widget. This is all so someone can compare temporal data at multiple locations. I have the tool written and it works fine in arcmap, but for the life of me I cannot figure out how to get it to work as a GP service. I published it, but I keep getting the error 000464 Cannot get exclusive schema lock. Either being edited or in use by another application. Any help on this would be greatly appreciated.

# Start script
#-----------------------------------------------------------------------------
import arcpy
import os

# Tool initialization
#-----------------------------------------------------------------------------
class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "Value_Extraction_Tool"
        self.alias = "Value Extraction Tool"

        # List of tool classes associated with this toolbox
        self.tools = [Tool]

class Tool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "Value Extraction Tool"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        DataSource = arcpy.Parameter(
		    displayName="DataSource",
		    name="DataSource",
		    datatype="DEWorkspace",
		    parameterType="Required",
		    direction="Input")

        InputPoint = arcpy.Parameter(
            displayName="InputPoint",
		    name="InputPoint",
		    datatype="DEFeatureClass",
		    parameterType="Required",
		    direction="Input")

        Output = arcpy.Parameter(
            displayName="OutputFC",
		    name="OutputFC",
		    datatype="DEFeatureClass",
		    parameterType="Required",
		    direction="Output")
            

        params = [DataSource, InputPoint, Output]
        return params

    def isLicensed(self):
        # Set whether tool is licensed to execute.
        return True

    def updateParameters(self, parameters):
        # Modify the values and properties of parameters before internal
        # validation is performed.  This method is called whenever a parameter
        # has been changed.
        return

    def updateMessages(self, parameters):
        #Modify the messages created by internal validation for each tool
        #parameter.  This method is called after internal validation."""
        return

    def execute(self, parameters, messages):

        # User input arguments
        DataSource = parameters[0].valueAsText
        InputPoint = parameters[1].valueAsText
        Output = parameters[2].valueAsText 

        # Variables
        Workspace = r"E:\Time_Series_Graphing_project\Development.gdb"
        DataTable = r"E:\Time_Series_Graphing_project\Development.gdb\TemporalData"
        DataRelationship = r"E:\Time_Series_Graphing_project\Development.gdb\DataRelationship"
        
        # Delete old verions
        if arcpy.Exists(DataTable):
            arcpy.Delete_management(DataTable)
            arcpy.AddMessage("Old table deleted")
        if arcpy.Exists(DataRelationship):
            arcpy.Delete_management(DataRelationship)
        if arcpy.Exists(InputPoint):
            arcpy.Delete_management(InputPoint)
        if arcpy.Exists(Output):
            arcpy.Delete_management(Output)

        # Handle all input point procesing
        arcpy.AddGeometryAttributes_management(InputPoint, "POINT_X_Y_Z_M", "", "", 4326)
        arcpy.CopyFeatures_management(InputPoint , Output)

        # Create a table to hold the temporal data
        arcpy.CreateTable_management(Workspace, "TemporalData")
        arcpy.AddField_management(DataTable, "POINTID", "SHORT")
        arcpy.AddField_management(DataTable, "DATAINDEX", "SHORT")
        arcpy.AddField_management(DataTable, "VALUE", "DOUBLE")

        # Loop through geometry attributes and get the x and y
        with arcpy.da.SearchCursor(InputPoint,"*") as cursor:
            PointIndex = 1
            for row in cursor:
                X = row[3]
                Y = row[4]
                arcpy.AddMessage(str(X) + " " + str(Y))
                # Get rasters and extract data at an X and Y        
                index = 0
                for (path, dirs, files) in os.walk(DataSource):
                    for ThisFile in files:
                        fName,fExt = os.path.splitext(ThisFile)
                        if fExt.upper() == ".IMG" or fExt.upper() == ".TIF":
                            RasterPath = path + "\\" + ThisFile

                            data = (arcpy.GetCellValue_management(RasterPath, str(X) + " " + str(Y), ""))
                            aquisition_date = arcpy.GetRasterProperties_management(in_raster = RasterPath, property_type = "ACQUISITIONDATE")

                            if str(aquisition_date).upper() == "UNKNOWN":
                                insertcursor = arcpy.InsertCursor(DataTable)
                                row = insertcursor.newRow()
                                row.setValue("POINTID", PointIndex)
                                row.setValue("DATAINDEX", index)
                                row.setValue("VALUE", data)
                                insertcursor.insertRow(row)
                                del insertcursor
                                index += 1

                PointIndex += 0
            del row
            del cursor

            # Create Relationship
            arcpy.CreateRelationshipClass_management(Output, DataTable, DataRelationship, "COMPOSITE", "","", "NONE", "ONE_TO_MANY", "NONE","POINTID","POINTID")
        return

0 Kudos
2 Replies
MorganWaterman
New Contributor III

Hi Grant Haynes‌,

When are you receiving the 000464 error? Upon publishing the GP service or when running it in a web app?

Is the web app/GP service hosted in Portal or ArcGIS Online?

Best,

Morgan

0 Kudos
GrantHaynes
Occasional Contributor

Hi Morgan, I have this running as a GP service on Arc Server, I get this error when the service executes on the server. I read that Arc Server GP tools only return primitive data types, they won't return tables and relationship classes, I think thats the root cause of this error.

0 Kudos