I know it's probably the opposite of what would generally be desirable, but I am trying to temporarily copy a Feature Class from a File GDB with Domains into a in_memory
intermediate FC without maintaining the source Domains.
I cannot prove this because I don't know how (where) to look for the in-memory FC I produce, but when I do
temp_folder = r'in_memory'
arcpy.arcpy.CopyFeatures_management(fc, os.path.join(temp_folder, 'temp'))
,I think I not only copy the entire source FC into the in_memory
workspace, but also the source FileGDB's Domains.
Can someone confirm this behaviour? Is there a way to avoid this using the same tool (CopyFeatures_management
) or (only if it's not possible) a similar tool?
I would like to keep using in_memory
for my intermediate file, rather than create physical intermediate files because:
- I would have to delete them
- I would have to properly check for errors within my script, handle them in order to delete intermediate files before they reach the 'delete' part of the script
in_memory
is faster because it uses RAM (is this true?)
I tried deleting the domains, but the code below seems to make ArcGIS crash all the time (imagine domains
comes from something like arcpy.ListDomains
)...
for d in domains:
arcpy.DeleteDomain_management(temp_folder, d)
2 Answers 2
When you copy a feature class to an in_memory workspace then all that I would have expected you to be copying is a feature class.
However, when I ran the test below it created output that indicates that the domains associated with a feature class are copied into the in_memory workspace, and if that in_memory feature class is copied out to a new file geodatabase then the domain is re-created in that new file geodatabase.
import arcpy
arcpy.env.overwriteOutput = True
arcpy.CreateFileGDB_management("C:/Temp","test")
arcpy.CreateTable_management("C:/Temp/test.gdb","testTable","","")
arcpy.AddField_management("C:/Temp/test.gdb/testTable","txtField","TEXT")
arcpy.AddField_management("C:/Temp/test.gdb/testTable","txtValue","TEXT")
cursor = arcpy.da.InsertCursor("C:/Temp/test.gdb/testTable",["txtField","txtValue"])
cursor.insertRow(("test1", "long text about test 1"))
del cursor
arcpy.TableToDomain_management("C:/Temp/test.gdb/testTable","txtField","txtValue","C:/Temp/test.gdb","testDomain","Test Domain","APPEND")
domains = arcpy.da.ListDomains("C:/Temp/test.gdb")
print "Domains in original:"
for domain in domains:
print domain.name
arcpy.CreateFishnet_management("C:/Temp/test.gdb/testFC","0 0","0 1","1","1","2","2","","NO_LABELS", "DEFAULT","POLYGON")
arcpy.AddField_management("C:/Temp/test.gdb/testFC","txtField","TEXT","","","","","NULLABLE","NON_REQUIRED","testDomain")
arcpy.CalculateField_management("C:/Temp/test.gdb/testFC","txtField",""""test" + str( !OID! )""","PYTHON")
arcpy.CreateFileGDB_management("C:/Temp","test2")
arcpy.CopyFeatures_management("C:/Temp/test.gdb/testFC","in_memory/testFC")
arcpy.CopyFeatures_management("in_memory/testFC","C:/Temp/test2.gdb/testFC")
domains = arcpy.da.ListDomains("C:/Temp/test2.gdb")
print "Domains in new file geodatabase:"
for domain in domains:
print domain.name
The output from the above was:
>>>
Domains in original:
testDomain
Domains in new file geodatabase:
testDomain
>>>
-
It appears (from OP's comment) that the domains are being copied through the in_memory into an output geodatabase. There may be a bit more to it.2016年10月07日 20:44:06 +00:00Commented Oct 7, 2016 at 20:44
-
I know this. I also know that the 'in_memory' workspace is a FileGDB itself, and I am wondering if when I do "CopyFeatures", the 'in_memory''s GDB itself changes its properties, inheriting the Domains from the source GDB from where the FC is copied from. Is that possible?umbe1987– umbe19872016年10月07日 20:44:45 +00:00Commented Oct 7, 2016 at 20:44
-
It should be easy to test whether a feature class copied into an in_memory workspace and out again to a new file geodatabase creates domains there.2016年10月07日 21:49:31 +00:00Commented Oct 7, 2016 at 21:49
-
I think it does create domains, and I am asking how to avoid this (if possible). I will come back to my script and update my question with the tool I am using to push the 'in_memory' temporary FC to the final GDB to let others replicate this behaviour. Meanwhile thanks for the replies.umbe1987– umbe19872016年10月07日 21:58:12 +00:00Commented Oct 7, 2016 at 21:58
Using @PolyGeo's script as basis, you can create an in_memory
feature class that does not carry the domain information, it's just a bit of work:
desc = arcpy.Describe("C:/Temp/test.gdb/testFC")
shape = desc.shapeType
spatref = desc.spatialReference
# create in_memory FC with the same spatial characteristics
temp = arcpy.CreateFeatureclass_management("in_memory", "testFC", shape,
spatial_reference=spatref)
fields = []
for field in arcpy.ListFields("C:/Temp/test.gdb/testFC"):
if field.type.upper() not in ["OID", "GEOMETRY"]:
fields.append(field.name)
# Now add the attribute characteristics
arcpy.AddField_management(temp, field.baseName, field.type, field.precision,
field.scale, field.length, field.aliasName,
field.isNullable, field.required)
# And populate with attribute information
with arcpy.da.SearchCursor("C:/Temp/test.gdb/testFC", fields) as sCursor:
with arcpy.da.InsertCursor(temp, fields) as iCursor:
for row in sCursor:
iCursor.insertRow(row)
arcpy.CopyFeatures_management("in_memory/testFC", "C:/Temp/test2.gdb/testFC")
Probably going to be a fair bit slower. Delete domains after the fact with the following:
for domain in arcpy.da.ListDomains(workspace):
arcpy.DeleteDomain_management(workspace, domain.name)
Note:
During creation of the in_memory
feature class, you can't use the input feature class as a template, as that will also carry the domain information (as it should)!
Explore related questions
See similar questions with these tags.
in_memory
then copying out again into a new geodatabase (that has no domains) and then just check whether it's included the domains.[d.name for d in arcpy.da.ListDomains(gdb)]
?