Programmatically Creating a Feature Class

10937
4
12-09-2010 08:34 PM
DanielLozier
New Contributor II
I'm trying to programmatically create a feature class by doing the following:

Calling CreateFeatureclass_management() to create the feature class

Calling AddField_management() in a loop to add all of the fields. (About 50 in total)

Calling DeleteField_management() to remove the default 'Id' field created by the CreateFeatureclass method.

When I run the script with the above code from the command line it runs 'relatively' fast (takes about 5 secs) but, once I bind the script to an ArcToolbox Tool (no changes to the script) it takes significantly longer (3min 20sec).

One thing that might point as to why its taking so long is that if I add the line 'arcpy.env.workspace="c:/workspace"' it speeds up some (1min 10sec) but still nowhere near the command line.

Also in general is there a better/faster way to programmatically create a feature class from scratch? I can't use the template parameter to the createFeatureclass_management method.
Tags (2)
4 Replies
KimOllivier
Occasional Contributor III
It must be the different default environment settings.
We need more detail of your setup to guess the issues.
Where are you creating the featureclass? SDE, versioning, local geodatabase?
Have you set your scratch workspace too?
These will all have defaults when you add a tool
What version and service pack?
Why can't you use a template?
0 Kudos
DanielLozier
New Contributor II
Mainly the two types of feature classes we will be creating are either a shapefile or a layer in a file geodatabase.  It's always going to be a file on the user's machine. No versioning or SDE.

I'm not setting a scratch workspace as far as I know.  At least not in the python code.

Im using ArcMap/ArcDesktop 10.0 Build 2414.  No service packs.

I can't use the template because I'm getting the list of fields from a service my python code calls and the fields can be different for every call so I don't have a predetermined format to base a template off of.

Here is some test code that replicates the issue.  I had to hand type this since the machine I'm working on doesn't have internet access so please excuse any typos.  It runs on the work machine.

import arcpy
import time

fc_workspace = "c:/test"
fc_name = "test.shp"
fc_fields = (
 ("a", "TEXT", None, None, 50, "", "NULLABLE", "NON_REQUIRED"),
 ("b", "LONG", 8, None, None, "", "NULLABLE", "NON_REQUIRED"),
 ("c", "SHORT", 4, None, None, "", "NULLABLE", "NON_REQUIRED"),
 ("d", "DOUBLE", 11, 8, None, "", "NULLABLE", "NON_REQUIRED"),
 ("e", "FLOAT", 5, 2, None, "", "NULLABLE", "NON_REQUIRED"),
 ("f", "DATE", None, None, None, "", "NULLABLE", "NON_REQUIRED")
 )

arcpy.env.workspace = fc_workspace

total_start = time.clock()

start = time.clock()
fc = arcpy.CreateFeatureclass_management(fc_workspace, fc_name, "POINT", spatial_reference="c:/Program Files/ArcGIS/Desktop10.0/Coordinate Systems/Geographic Coordinate Systems/World/WGS 1984.prj")
end = time.clock()
arcpy.AddMessage("Create Feature Class %.3f" % (end - start))

start = time.clock()
for fc_field in fc_fields:
 arcpy.AddField_management(fc, *fc_field)
end = time.clock()
arcpy.AddMessage("Create Fields %.3f" % (end - start))

start = time.clock()
arcpy.DeleteField_management(fc, "Id")
end = time.clock()
arcpy.AddMessage("Delete Id Field %.3f" % (end - start))

total_end = time.clock()
arcpy.AddMessage("Total %.3f" % (total_end - total_start))


Output when I run it just as a regular python script:
Create Feature Class 0.313
Create Fields 0.313
Delete Id Field 0.044
Total 0.670


Output when I bind the script to a ArcToolbox Tool.  I just create a standard script tool with no parameters.
Executing: testcreatefc
Start Time: Mon Dec 13 19:42:04 2010
Running script testcreatefc...
Create Feature Class 0.628
Create Fields 2.713
Delete Id Field 0.627
Total 3.968
Completed script testcreatefc...
Succeeded at Mon Dec 13 19:42:09 2010
(Elapsed Time: 5.00 seconds)
0 Kudos
KimOllivier
Occasional Contributor III
I got exactly the opposite result.

I ran the example on my laptop, Windows 7, ArcGIS 10 SP1, Intel Core I5.
Running from Pythonwin:
Total 0.751 (Units??)
Elapsed time 00:00:02.999500 ie 3 seconds

Running from ArcMap as a tool, foreground,in process:
Total 0.913
Elapsed time  0:00:00.95100 ie less than 1 second
Turning off foreground process
Total 0.335
Turning off inprocess
Total 0.338

Just for fun I pasted it into the interactive Python window:
Total 10.395
Elapsed time 10.434 seconds
This seems to be because each command was executed separately
with the result log echoed to the window

It will make a big difference if you run the script out of process.
0 Kudos
DanielLozier
New Contributor II
Alright so I think I've figured out the problem. Or at least a large chunk of it.

All of the geoprocessing tools in this script seem to do something with the arcpy.env.workspace and arcpy.env.scratchWorkspace when the script is attached to a geoprocessing tool even when the feature class I'm working with is not in either of these workspaces.

It makes sense to me why CreateFeatureclass, AddField, and DeleteField could use arcpy.env.workspace but I don't understand why they would use scratchWorkspace.

Since I wasn't explicitly setting the scratchWorkspace in the script the tools seem to do "more work" in the default geodatabase for my current map document in ArcMap.  In my case the default Geodatabase was the default one that ESRI creates, My Documents/ArcGIS/Default.gdb.  The corporate environment I'm working in puts our My Documents folder on a network drive so that is why it was running so slow.  I said "more work" because the 3 arcpy tools still seem to do something with the default geodatabase even when I explicitly set the workspace and scratchWorkspace to the location where the feature class should be created. (i.e. in the script above when I added the line arcpy.env.scratchWorkspace = fc_workspace it only sped up the total time from 4 seconds to 2 seconds.  The units in the output are seconds)

If I set the default geodatabase to one on my local drive and add "arcpy.env.scratchWorkspace = fc_workspace" to the script I got the same results you're seeing where when attached to a geoprocessing tool the script is 20-25% slower.  I'm not looking at the total time this sample script takes to run (i.e. the "Elapsed time XX:XX:XX") because that ~2 second difference between it and "Total X.XXX" that occurs when the script runs standalone is a fixed amount.  The 2 seconds of additional time happens on the "import arcpy" line and is the same no matter how many calls to arcpy geoprocessing tools I make.  My guess is that the standalone script has to check my ArcDesktop license and/or fire up some process which is already done when running from ArcMap.  My real code makes hundreds of arcpy calls so those 2 seconds get drowned out.

I tried turning off inprocess but that caused the call to AddField_management in the script to fail with an error of "(<class 'arcgisscripting.ExecuteError'>, ExecuteError('ERROR 000582: Error occurred during execution.\n',), <traceback object at 0x0516D030>)".  I'm guessing that's a bug that was fixed in sp1.  Once I can get a hold of sp1 I will try it again.  Just fired off the request to the bureaucracy.
0 Kudos