Select to view content in your preferred language

Join csv to multiple feature classes

695
5
12-14-2020 07:35 AM
by Anonymous User
Not applicable

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?

Tags (2)
0 Kudos
5 Replies
DanPatterson
MVP Esteemed Contributor

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?


... sort of retired...
DavidPike
MVP Frequent Contributor

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.

 

by Anonymous User
Not applicable

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.

 

0 Kudos
BlakeTerhune
MVP Regular Contributor

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.

by Anonymous User
Not applicable

@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.

0 Kudos