5

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:

  1. I would have to delete them
  2. 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
  3. 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)
4
  • 1
    You can test what it does with domains by copying to in_memory then copying out again into a new geodatabase (that has no domains) and then just check whether it's included the domains.
    – Midavalo
    Commented Oct 7, 2016 at 19:21
  • It is exactly why I am asking this. The output is processed and put in a newly created FileGDB (i.e. without Domains), but when it is populated with the temporary FC, it populates with all the Domains.
    – umbe1987
    Commented Oct 7, 2016 at 20:41
  • An in_memory workspace resembles a file geodatabase but is not one.
    – PolyGeo
    Commented Oct 7, 2016 at 21:46
  • 1
    If it didn't copy the domains, what would be the expected behavior if you had a domain on an integer field with a string description? In deleting the domains, are you accessing by name: [d.name for d in arcpy.da.ListDomains(gdb)]?
    – Paul
    Commented Oct 7, 2016 at 23:59

2 Answers 2

6

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
>>> 
4
  • 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.
    – Midavalo
    Commented 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
    Commented 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.
    – PolyGeo
    Commented 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
    Commented Oct 7, 2016 at 21:58
1

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)!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.