Hi,
I have a csv as follow;
ID NAME Category Model
H1 Bridge BG AB1
H2 Tunnel TL AB2 etc etc
I have a geodatabase with multiple feature classes:
Working.gdb (within each FC there is a FILENAME field with the Model number)
FcOne (FILENAME: AB1, ID: Empty, NAME: Empty, Category: Empty)
FcTwo etc etc
I am trying to join the csv to all the FCs and field calculate the empty fields in the gdb with those in the csv.
I am using Blakes code :
#Join CSV and populate fields
csv_values = {
row[3]: {"ID": row[0], "NAME": row[1], "Category": row[2]}
for row in arcpy.da.SearchCursor(Add_CSV, ["ID", "NAME", "Category", "Model"])
}
for fc in fcList:
with arcpy.da.UpdateCursor(fc, ["FILENAME", "ID", "NAME", "CATEGORY"]) as u_cursor:
for filename, id, name, category in u_cursor:
csv_record = Add_CSV.get(filename)
assert csv_record, "No value found for {} filename {} in CSV".format(fc, filename)
id = csv_record["ID"]
name = csv_record["NAME"]
category = csv_record["Category"]
u_cursor.updateRow([filename, id, name, category])
I get the following error:
csv_record = Add_CSV.getValue(filename)
AttributeError: 'str' object has no attribute 'getValue'
Not sure how to fix this. Can you assist?
Code formatting ... the Community Version - GeoNet, The Esri Community would help with format and indentation checking.
What did the code do? or have you even tested it?
I'm guessing there is indentation in the code, please use the formatting options to make it readable.
What does each FC look like after the join? The data model is confusing and not very well explained, i.e. why is BRIDGE a field in the FC and why are they separate FCs?
Unsure what you want to achieve with the cursor how it is, it's assigning each field value to itself for each row. If you want to do field value reassignment, import all the fields you need in the [HS2FieldCalculator] and reassign them by index.
Thanks @DanPatterson @DavidPike . Yes, sorry that was due to a paste error.
Join field only work for the first feature class in the gdb. It wont join the other FCs.
Once I figure out how to join a single csv to all the feature classes within my geodatabase I can just calculate over the fields I need.
Thanks.
I've come to prefer simply reading the contents of the join table (your CSV) into a dictionary and then looping through each feature class and looking up the field values to calculate. For example, if Model field is your key field, read the data into a dictionary like:
csv_values = {
row[3]: {"ID": row[0], "NAME": row[1], "Category": row[2]}
for row in arcpy.da.SearchCursor(csv, ["ID", "NAME", "Category", "Model"])
}
So each key is a unique Model (assuming there are no duplicates here) and the value is another dictionary with the other fields. This would let you look up the values like:
for fc in fcList:
with arcpy.da.UpdateCursor(fc, ["FILENAME", "ID", "NAME", "Category"]) as u_cursor:
for filename, id, name, category in u_cursor:
csv_record = csv_data.get(filename)
assert csv_record, "No value found for {} filename {} in CSV".format(fc, filename)
id = csv_record["ID"]
name = csv_record["NAME"]
category = csv_record["Category"]
u_cursor.updateRow([filename, id, name, category])
If you have millions of records, this might hog memory.
@BlakeTerhune I worked around an error i was getting . The next error is as follow:
AssertionError: No value found for _1XC07_CED_EE_EFB_ES04_CGG0_000038 filename 1XC07-CED-EE-EFB-ES04-CGG0-000038 in CSV
_1XC07_CED_EE_EFB_ES04_CGG0_000038 is the name of one of the feature classes in my geodatabase. Its seems as though it is trying to match the "model" in CSV to the title of feature and not the "FILENAME" field within the feature class.
Any help would be appreciated.