Automatically derive migration from schema

Hi there, I just followed the “getting started” article and started playing around with Ecto. I was pleased to discover mix phx.gen.schema, because it makes it easier to create a schema and its migration in one go. I do have two questions, related to two use cases:

  1. Sometimes, for big types, it is cumbersome to write out all fields in the terminal. It would be nice to write things out in a schema definition and have the migration be generated afterwards. Is there any way to do this?
  2. Sometimes we modify an existing schema and need a new migration. Is it possible to generate the migration automatically, or do we have to do it manually? I assume it is a manual process, but since I have seen this feature in other libraries (.NET EF Core) I thought I would ask just in case.

Thanks in advance!

The generator is a convenience, but the migrations are the ultimate source-of-truth; for instance, column options like null: false don’t appear in the schema at all and so couldn’t be generated.

1 Like

What you ask for does not exist in a popular library – as far as I’m aware.

If I were to author such an effort I’d honestly not know how to express all these details on the command line as plain text.

Any ideas?

For more complex cases you don’t want to do this; you can have more than one schema for a table (different use cases might have different views) and this is a way to restrict domain access and limit how many columns your query performs a pull on.

3 Likes

The Ash Framework (https://www.ash-elixir.org) has migration generation based on model changes and it seems pretty reliable. But it requires adoption of Ash, which requires a well-informed decision as it ends up being a pretty fundamental part of your stack. You could dig through the source code to see how the migrations are calculated and maybe spin up a small project to see how it works. “Resource snapshots” are recorded each time a migration is created in order to calculate the difference. In that sense it works a little like model-first in EF, but without the 15-minute wait each time.

1 Like

That’s it for me as well. Decoupling the illusion that tables map 1:1 to schemas is really important and a big distinction to what I’ve seen elsewhere. Ecto doesn’t care what you do in the db for as long as the data coming out maps to a given schema. The table name given to schema … do is really only a means of telling constructed queries which table to use – and that’s just a default overridable with {"other_table", Schema} for query building.

I can certainly see the convenience for cases where schema and migration do indeed align 1:1, but that’s an assumption ecto explicitly doesn’t make.

1 Like