The String.to_atom/1 call in your code is dangerous if the data is coming from the user or some other dynamic source. Atoms are not garbage collected, so a caller could send different atoms until your VM’s atom table fills up and then it crashes. (Maybe we should rename it to String.dangerous_to_atom/1?)
Since you know your schema / DB structure, you should know what fields exist in the DB. So you should be able to write an explicit mapping function from string keys to atom keys, that you can use before insert_all.
You can’t get a map with atom keys from an end-user because an end-user can be malicious. You can call String.to_existing_atom, but I suggest you try maps with string keys first.