Adding calculated field on save

defmodule Address.AddressCtx.Address do
  use Ecto.Schema
  import Ecto.Changeset

  schema "addresses" do
    field :street1, :string, size: 250, default: ""
    field :street2, :string, size: 250, default: ""
    field :city, :string, size: 100, default: ""
    field :state, :string, size: 2, default: ""
    field :zip, :string, size: 32, default: ""
    field :country, :string, size: 3, default: "US"
    field :fingerprint, :string, size: 32, default: ""
    timestamps()
  end

  @doc false
  def changeset(address, attrs) do
    address
    |> cast(attrs, [:street1, :street2, :city, :state, :zip, :country, :fingerprint])
    |> validate_required([:street1, :city, :state, :zip, :country])
    |> append_fingerprint()
    |> unique_constraint(:fingerprint, message: "Fingerprint already in use")
  end


  defp append_fingerprint(changeset) do
    case changeset do
      %Ecto.Changeset{valid?: true, changes: %{address: address}} ->
        IO.puts(address)
        put_change(changeset, :fingerprint, get_fingerprint(address))
      _ ->
        changeset
    end
  end


  @doc """
   Simple md5 fingerprint
  """
  def get_fingerprint(address) do
    address.street1 <> address.street2 <> address.city <> address.state <> address.zip <> address.country
    |> String.upcase
    |> :erlang.md5
    |> Base.encode16(case: :lower)
  end

end

Here’s my schema file – the get_fingerprint() function seems to work when I test it in iex, so I’m thinking I’ve missed something in the cast() or other functions inside changeset since I’m not fully understanding the pieces of that.

Are there times when you would want to define a field in the database but not list it in the fields passed to cast()?