Julia : update mutable struct by matching it's name to value of DataFrame column

Viewed 116

I would like to use a macro to mutate one of a set of mutable structs, based on the value of an id column in a DataFrame, where the id column matches the name of the structs. I have a function that returns a dataframe created from a MySQL table :

function groups()
    log = DBInterface.execute(con, "SELECT * FROM pgdb1.groups")
    df  = DataFrame(log)
    return df
end

This is the dataframe, which has 2 columns, id and pop :

2×2 DataFrame
 Row │ id       pop     
     │ String   String
─────┼───────────────────
   1 │ yg_1     6
   2 │ jyg_1    4

I have 2 structs, which match those ids, and i would like to update them based on rows of the dataframe :

mutable struct jyg_1
    pop::Int
end

mutable struct yg_1
    pop::Int
end

I have a macro that takes the dataframe. Based on the id of that row, i would like for it to update the struct that shares the same name as the row's id. Below is some pseudocode to give a sense of what i was thinking but theres probably a much better way to do it.

macro filter()
    for row ∈ eachrow(groups())      
#       if row.id == [ some element in a list of stringified structs ]
#       update the jyg_1 or yg_1 struct with group.pop
#   DBInterface.execute(con, "INSERT INTO pgdb1.groups (pop) VALUES ('$pop' );")
#       end
    end
end

I'm not sure if someone could give me a push in the right direction. Thanks for considering this question!

1 Answers

You basically need convert the class name to Symbol and than eval it and thus obtain object. I believe you do not need a macro for that.

For an example consider df:

julia> df = DataFrame(id=["yg_1", "jyg_1"], pop=[4,6])
2×2 DataFrame
 Row │ id      pop
     │ String  Int64
─────┼───────────────
   1 │ yg_1        4
   2 │ jyg_1       6

You can do:

julia> map.(eval.(Symbol.(df.id)), df.pop)
2-element Vector{Any}:
 yg_1(4)
 jyg_1(6)

Which is probably what you wanted.

Related