Arcpy - FeatureClassToFeatureClass

5526
10
Jump to solution
11-25-2015 06:29 AM
TrilliumLevine1
Occasional Contributor

Hello All,

I have a dictionary with a list of feature class paths (keys) and destination feature datasets (values) that I'm trying to use to do a batch FeatureClassToFeatureClass operation with.  No matter what I've tried, however, I keep getting the same error when I run the script:

Here is the code I'm running to do this:

for key, value in FCFDdict.iteritems():
        inFC = str(key)
        destination = str(value)
        outFC = str(os.path.basename(key))
        arcpy.env.workspace = destination
        arcpy.FeatureClassToFeatureClass_conversion(inFC, destination, outFC)

My dictionary is populated with unicode strings, and looks like this:

{
u'C:\\Scripts\\Redefine Projection\\MyGeodatabase.gdb\\FD_A\\infotafeln_1': u'C:\\Scripts\\Redefine Projection\\MyGeodatabase.gdb\\FD_A_redefined', 
u'C:\\Scripts\\Redefine Projection\\MyGeodatabase.gdb\\FD_B\\sielhautproben_2': u'C:\\Scripts\\Redefine Projection\\MyGeodatabase.gdb\\FD_B_redefined', 
u'C:\\Scripts\\Redefine Projection\\MyGeodatabase.gdb\\FD_B\\infotafeln_2': u'C:\\Scripts\\Redefine Projection\\MyGeodatabase.gdb\\FD_B_redefined'
}

Anyone out there have any idea what I'm doing wrong here?  I've also tried feeding FeatureClassToFeatureClass the key's basename, to no avail.  Any feedback is greatly appreciated!

0 Kudos
1 Solution

Accepted Solutions
FreddieGibson
Occasional Contributor III

Hi Trillium,

Your problem should be that you're trying to export the feature class to a new feature dataset with the same name. Names must be unique within a geodatabase. So in your case you can't have both FD_A\infotafeln_1 and FD_A_redefined\infotafeln_1. You would have to rename the new feature class to another unique name that doesn't exist in the entire geodatabase. To prove this I've provided the code I used to test. You should be able to run this on your machine to confirm. You'll see in the new instance that I add an underscore to the name to make it unique.

import arcpy
import os
import unittest


# This will create a geodatabase similar to yours
def CreateUserEnvironment(gdbPath):
    gdbContents = [("FD_A", ["infotafeln_1"]), 
                   ("FD_B", ["sielhautproben_2", "infotafeln_2"]), 
                   ("FD_A_redefined", []), 
                   ("FD_B_redefined", [])]
    
    if arcpy.Exists(gdbPath):
        arcpy.management.Delete(gdbPath)
        
    arcpy.management.CreateFileGDB(os.path.dirname(gdbPath), os.path.basename(gdbPath))
    
    for ds, fcs in gdbContents:
        dsPath = arcpy.management.CreateFeatureDataset(gdbPath, ds, arcpy.SpatialReference(3857))
        for fc in fcs:
            arcpy.management.CreateFeatureclass(dsPath, fc, "POINT", spatial_reference=arcpy.Describe(dsPath).spatialReference)
            
def TestWorkflow(gdbPath):
    expPath = {"{0}\\FD_A\\infotafeln_1".format(gdbPath):"{0}\\FD_A_redefined".format(gdbPath),
               "{0}\\FD_B\\sielhautproben_2".format(gdbPath):"{0}\\FD_B_redefined".format(gdbPath),
               "{0}\\FD_B\\infotafeln_2".format(gdbPath):"{0}\\FD_B_redefined".format(gdbPath)}
    
    for k,v in expPath.items():
        # Workflow you're currently implementing
        try:
            print("Exporting to new feature dataset with same name")
            arcpy.conversion.FeatureClassToFeatureClass(k, v, os.path.basename(k))
        except arcpy.ExecuteError as e:
            print(e.message)
            
        # Workflow I'm suggesting
        try:
            print("Exporting to new feature dataset with different name")
            arcpy.conversion.FeatureClassToFeatureClass(k, v, os.path.basename(k) + "_")
            print(arcpy.GetMessages())
        except arcpy.ExecuteError as e:
                    print(e.message)        
                    
        print("*"*25 + "\n")
        


if __name__ == "__main__":
    gdbPath = os.path.join(os.path.dirname(__file__), "MyData.gdb")
    CreateUserEnvironment(gdbPath)
    TestWorkflow(gdbPath)
    

View solution in original post

10 Replies
MichaelVolz
Esteemed Contributor

Can you put in any print statements to see exactly how the variables are being populated?  I'm thinking that a path to a file is expected, but it is not getting added to the variable as expected.

TrilliumLevine1
Occasional Contributor

Thanks for your response, Michael.

I changed this up a little bit to set the workspace first, and to have it with the correct syntax, see the code below -- extra slashes necessary since they are escape characters in python:

for key, value in FCFDdict.iteritems():
        destination = str(value)
        workspace = arcpy.env.workspace = destination.replace("\\", "\\\\")
        inFC = str(os.path.basename(key))
        outFC = str(key)
        arcpy.FeatureClassToFeatureClass_conversion(inFC, workspace, outFC)

When I run this, I now get an error that tells me that my dataset doesn't exist:

Although it clearly does:

Anyway, here's a print of my variables:

0 Kudos
MichaelVolz
Esteemed Contributor

Are you creating new feature classes in the file geodatabase or trying to overwrite existing feature classes?

Your destination path has "\\" while your out path has "\".

Maybe out should just be referring to the name of the feature class to be created and not the entire path (At least that's how I read the Help documentation).

0 Kudos
TrilliumLevine1
Occasional Contributor

From what I can tell from the help, you're right -- it looks like the in and out just require names, while the only parameter requiring a path is the destination. Also looks like there should be forward slashes in the destination path.

I'm trying to export each Feature Class designated by the key to the Feature Dataset designated by the value.  Right now I've got:

for key, value in FCFDdict.iteritems():
        destination = env.workspace = str(value.replace('\\', '/'))
        print 'destination: ' + destination
        inFC = str(os.path.basename(key))
        print 'inFC: ' + inFC
        inFCpath = str(key)
        print 'inFCpath: ' + inFCpath
        outFC = inFC
        print 'outFC: ' + outFC
##        arcpy.FeatureClassToFeatureClass_conversion(inFC, destination, outFC)

which gives me:

inFCpath is not being used, it's just for my reference to make sure it's correct.  Nevertheless, when I uncomment the last line, I'm still getting:

0 Kudos
MichaelVolz
Esteemed Contributor

Is FD_A_redefined a feature dataset?  If so, can you try just to perform a feature to feature class conversion to a feature class outside a feature dataset to see if its the feature dataset that is causing the issue?

0 Kudos
FreddieGibson
Occasional Contributor III

Hi Trillium,

Your problem should be that you're trying to export the feature class to a new feature dataset with the same name. Names must be unique within a geodatabase. So in your case you can't have both FD_A\infotafeln_1 and FD_A_redefined\infotafeln_1. You would have to rename the new feature class to another unique name that doesn't exist in the entire geodatabase. To prove this I've provided the code I used to test. You should be able to run this on your machine to confirm. You'll see in the new instance that I add an underscore to the name to make it unique.

import arcpy
import os
import unittest


# This will create a geodatabase similar to yours
def CreateUserEnvironment(gdbPath):
    gdbContents = [("FD_A", ["infotafeln_1"]), 
                   ("FD_B", ["sielhautproben_2", "infotafeln_2"]), 
                   ("FD_A_redefined", []), 
                   ("FD_B_redefined", [])]
    
    if arcpy.Exists(gdbPath):
        arcpy.management.Delete(gdbPath)
        
    arcpy.management.CreateFileGDB(os.path.dirname(gdbPath), os.path.basename(gdbPath))
    
    for ds, fcs in gdbContents:
        dsPath = arcpy.management.CreateFeatureDataset(gdbPath, ds, arcpy.SpatialReference(3857))
        for fc in fcs:
            arcpy.management.CreateFeatureclass(dsPath, fc, "POINT", spatial_reference=arcpy.Describe(dsPath).spatialReference)
            
def TestWorkflow(gdbPath):
    expPath = {"{0}\\FD_A\\infotafeln_1".format(gdbPath):"{0}\\FD_A_redefined".format(gdbPath),
               "{0}\\FD_B\\sielhautproben_2".format(gdbPath):"{0}\\FD_B_redefined".format(gdbPath),
               "{0}\\FD_B\\infotafeln_2".format(gdbPath):"{0}\\FD_B_redefined".format(gdbPath)}
    
    for k,v in expPath.items():
        # Workflow you're currently implementing
        try:
            print("Exporting to new feature dataset with same name")
            arcpy.conversion.FeatureClassToFeatureClass(k, v, os.path.basename(k))
        except arcpy.ExecuteError as e:
            print(e.message)
            
        # Workflow I'm suggesting
        try:
            print("Exporting to new feature dataset with different name")
            arcpy.conversion.FeatureClassToFeatureClass(k, v, os.path.basename(k) + "_")
            print(arcpy.GetMessages())
        except arcpy.ExecuteError as e:
                    print(e.message)        
                    
        print("*"*25 + "\n")
        


if __name__ == "__main__":
    gdbPath = os.path.join(os.path.dirname(__file__), "MyData.gdb")
    CreateUserEnvironment(gdbPath)
    TestWorkflow(gdbPath)
    
TrilliumLevine1
Occasional Contributor

Hi Freddie,

Thanks so much for for your detailed and lengthy response, I realized that naming problem as I was playing with this.  I guess once the FC's are done transferring I'll have to first delete the old origin FD's and then rename the new FC's...annoying, but I guess that's the clearest path.

0 Kudos
TrilliumLevine1
Occasional Contributor

So basically to get this to work, I used a couple of lines from Freddie's code -- my code now looks like this:

workspace = os.path.join(os.path.dirname(__file__), "MyGeodatabase.gdb")
for k, v in FCFDdict.items():
        try:
            arcpy.conversion.FeatureClassToFeatureClass(k, v, os.path.basename(k) + "_trillium")
        except arcpy.ExecuteError as e:
            print(e.message)