I need to copy some fields from one shapefile to another existing one, preferably using Arcpy. Below is my code that checks for common fields between two shapefiles. Can I use this and add code to copy the fields that are not already in the destination shapefile from the original? What function will do that for me? I do not want data to transfer over--just the fields. Thank you!
Hi Doug
Try this:
shp01 = r'C:\tmp\New_Shapefile01.shp'
shp02 = r'C:\tmp\New_Shapefile02.shp'
fieldsShp01 = arcpy.ListFields(shp01)
fieldsShp02 = arcpy.ListFields(shp02)
newFields = []
for field01 in fieldsShp01:
exists = False
for field02 in fieldsShp02:
if (field01.name == field02.name and field01.type == field02.type and field01.length == field02.length):
exists = True
# print("The {0} field with a type of {1} and a length of {2} exists in both shapefiles"
# .format(field01.name, field01.type, field01.length))
if (exists == False):
# print("The {0} field with a type of {1} and a length of {2} exists only in shp 01"
# .format(field01.name, field01.type, field01.length))
newFields.append([field01.name, field01.type, field01.length])
for field in newFields:
arcpy.AddField_management(shp02, field[0], field[1], "", "", field[2], "", "NON_NULLABLE","NON_REQUIRED","")
print("The {0} field with a type of {1} and a length of {2} was added to shp 02"
.format(field[0], field[1], field[2]))
For documentation on the Add Field tool you can navigate here.
Regards,
Leo
Hi Leo,
Thank you so much. I'll take a close look at this over the weekend. But for now it is throwing an exception at the AddField_management() line:
... for field in newFields:
... arcpy.AddField_management(shp02, field[0], field[1], "", "", field[2], "", "NON_NULLABLE","NON_REQUIRED","")
... print("The {0} field with a type of {1} and a length of {2} was added to shp 02"
... .format(field[0], field[1], field[2]))
...
Runtime error Traceback (most recent call last): File "<string>", line 22, in <module> File "j:\apps\arcgis\desktop10.4\arcpy\arcpy\management.py", line 3149, in AddField raise e ExecuteError: ERROR 000800: The value is not a member of TEXT | FLOAT | DOUBLE | SHORT | LONG | DATE | BLOB | RASTER | GUID.
So I removed field[0] and field[1], then got this error:
Runtime error Traceback (most recent call last): File "<string>", line 22, in <module> File "j:\apps\arcgis\desktop10.4\arcpy\arcpy\management.py", line 3149, in AddField raise e ExecuteError: ERROR 000310: The Field name must not start with a number
There are no field names that start with a number in the source layer. Like I said, I'll work with this later.
Thanks Again!
Doug
Hi Doug,
Try moving the print statement that you use right after the add field function up so that it prints what is supposed to be added. I think that will give you the info you need to solve the problem. Based on the error you received I believe that your script is trying to add a field with an invalid type to the target shapefile.
Micah
I finally got a chance to get back into this and got it working. I moved the last print statement above the add field call :
... print("The {0} field with a type of {1} and a length of {2} was added to shp 02"
... .format(field[0], field[1], field[2]))
... arcpy.AddField_management(shp02, field[0], field[1], "", "", field[2], "", "NON_NULLABLE","NON_REQUIRED","")
...
..... and got this error message: ... for field in newFields:
The OBJECTID field with a type of OID and a length of 4 was added to shp 02
Runtime error Traceback (most recent call last): File "<string>", line 24, in <module> File "j:\apps\arcgis\desktop10.4\arcpy\arcpy\management.py", line 3149, in AddField raise e ExecuteError: ERROR 000800: The value is not a member of TEXT | FLOAT | DOUBLE | SHORT | LONG | DATE | BLOB | RASTER | GUID.
So I added a nested IF to bypass the adding of OBJECTID because it looked like it balked at adding it. I suppose this is because every shp has a field like that by default.
if (exists == False):
... if (field01.name != 'OBJECTID'):
newFields.append([field01.name, field01.type, field01.length])
Thanks again for the assistance!
Glad to hear it! Since sometimes OID fields have a name besides OBJECTID, an even more robust approach would be:
if (field01.type != 'OID'):
Happy scripting, Doug.
Hi Doug
Please try Micah's suggestion (place print statement before arcpy.AddField_management) to see the properties (name, type, length) of the field you're trying to add.
Regards,
Leo