Hi folks,
I’m working with football data in Mix project. My API does not support event system . Way that I take data is time based (cron like). So far every record in Postgres tables have hash field based on data hash. If my hash is different than I go to update, else do nothing.
What is best way to do this logic? I’m thinking in model to create function that contains this logic (upsert_by_…), get record (by uniq id non AI) if exists, perform calculations and execute insert/update/nothing.
I’m working with hash to eliminate multi value comparison.
1 Like
It’s not a popular theme, let me show you some example:
defmodule Api.Upsert do
alias Api.Repo
defmacro __using__(_) do
quote do
def upsert(data) do
record = Repo.get_by(__MODULE__, api_id: data.api_id)
save_to_db(record, data)
end
defp save_to_db(nil, data) do
IO.inspect data
changeset = __MODULE__.changeset(data)
IO.inspect changeset
case Repo.insert(changeset) do
{:ok, struct} -> struct
{:error, changeset} -> {:error, "Insert #{__MODULE__} failure!", changeset}
end
end
defp save_to_db(record, data) do
case String.equivalent?(record.hash, data.hash) do
true -> record
_ -> update(record, data)
end
end
defp update(record, data) do
changeset = __MODULE__.changeset(data, record)
case Repo.update(changeset) do
{:ok, struct} -> struct
{:error, changeset} -> {:error, "Update #{__MODULE__} failure!", changeset}
end
end
end
end
end
This macro is included in my models. Are you see some mistakes?
1 Like
I seriously cannot understand what exactly are you trying to achieve.
Instead of giving us details about your code, can you tell us what is your input and desired output?
Hi, my goal is to store API data in DB. Data is big, so I decided to update them only if there is difference (cause update is very slow operation). My input data is models like Country{Name}, League{Name,Country}, Team{Name,Venue,League}, Fixtures{TeamA,TeamB,Date} and so on. And I do not want to write comparrisions manualy (it`s a ton of code).