Storing any Elixir data in Postgres

Disclaimer : this is just an experiment. I don’t know how f… up it is to store Erlang’s terms in a SQL DB.

You can store any Elixir data (aka Erlang’s term) in Postgres. Here’s how you do it, step-by-step.

Step 1 : The migration

mix ecto.gen.migration my_term

Edit the migration :

defmodule BinToDb.Repo.Migrations.MyTerm do
use Ecto.Migration
  def change do
create table(:terms) do
add :content, :binary
end
end
end

Then migrate :

mix ecto.migrate

Step 2 : The type

You’ll need to create a new type to store terms. Here’s the file :

defmodule Term do
@behaviour Ecto.Type
def type, do: :binary
def cast(bin), do: {:ok, bin |> :erlang.binary_to_term()}
def load(bin), do: {:ok, bin |> :erlang.binary_to_term()}
def dump(bin), do: {:ok, bin |> :erlang.term_to_binary()}
end

Step 3 : The schema

Let’s write a simple schema :

defmodule BinToDb.MyTerm do
use Ecto.Schema
schema "terms" do
field :content, Term
end
end

Step 4 : Enjoy

Now that everything’s ready let’s try some iex :

alias BinToDb.{Repo, MyTerm}
Repo.insert(%MyTerm{content: [1, "2", %{title: "yay"}])
t = Repo.one(MyTerm)
t.content
# [1, "2", %{title: "yay"}]