Back to Solutions
Problem

How to change a field type in an Ecto embedded schema from string to array with a migration while preserving existing JSONB data

Shared by Contributor
0 upvotes
0 downvotes
+0 score
Log in to vote
Solution

Update Schema Definition

  • Change the embedded schema field type from :string to {:array, :string}
embedded_schema do
field :tags, {:array, :string}
end

Create Migration

  • Generate migration: mix ecto.gen.migration update_tags_field

Implement Up Migration (String → Array)

execute("""
UPDATE my_table
SET embedded_schema_field = jsonb_set(
embedded_schema_field,
'{tags}',
to_jsonb(string_to_array((embedded_schema_field->>'tags'), ','))
)
WHERE embedded_schema_field ? 'tags';
""")

Implement Down Migration (Array → String)

execute("""
UPDATE my_table
SET embedded_schema_field = jsonb_set(
embedded_schema_field,
'{tags}',
to_jsonb(array_to_string((embedded_schema_field->'tags')::text[], ','))
)
WHERE embedded_schema_field ? 'tags';
""")

Key Points

  • Embedded schemas are stored in JSONB columns, not separate tables
  • Use jsonb_set() to update specific nested keys safely
  • Use string_to_array() and array_to_string() for type conversion
  • Use to_jsonb() to maintain JSONB format compatibility
  • Update any existing queries to handle the new list type
Tags
domain
database
framework
ectophoenix
language
elixir
platform
backend
Created February 03, 2026