Search code examples
postgresqlelixirphoenix-frameworkecto

A PostgreSQL array of varchar(custom_size) in Elixir's Ecto


I have an Ecto schema like this:

schema "quotes" do
  field :quote, :string
  field :tags, {:array, :string}

  timestamps()
end

In a corresponding migration there's:

create table(:quotes) do
  add :quote, :string, size: 145
  add :tags, {:array, :string}

  timestamps()
end

I want each tag in tags to be with a maximum size of 140. How to specify this constraint in the migration? My goal is to have an array of varchar(140) in a resulting PostgreSQL table instead of a more 'spacy' default (255?).


Solution

  • add accepts any atom as the column type and passes it as-is to the Adapter and the PostgreSQL Adapter sends unknown types as-is to the database, which means we can specify the exact type, i.e. varchar(140) as the second element of {:array, _}, it just needs to be an atom.

    add :tags, {:array, :"varchar(140)"}
    

    I've tested this and running the migration correctly creates the column of the type need.

    my_app_dev=# \d posts
                                      Table "public.posts"
      Column  |           Type           |                     Modifiers
    ----------+--------------------------+---------------------------------------------------
     ...
     tags     | character varying(140)[] |
    

    There's no need to change anything in the schema. The type there should remain {:array, :string}.