Schema.rb table and column order

When multiple people are working on a single Rails codebase and they add migrations with new columns (or tables) and run the migrations in different order there is a problem with schema.rb. After this every time migrations are run the columns swap places if the previous version of the schema.rb file has been commited by the other developer who did run the migrations in different order.

Because of this the developers have to discard the lines where columns swap places to keep the source control clean. Could this be fixed by putting the tables and columns on schema.rb in alphabetical order? Or are people relying on the database’s order of the tables and columns?

It seems you could implement it by sticking .sort_by(&:name) to rails/schema_dumper.rb at 3f96b6973b82ad17e443dd1d21be05996fb6fbf0 · rails/rails · GitHub

– Vesa Vänskä

vesa@vesavanska.com

Great idea! Once schemas do get out of sync this crops every time a developer runs db:migrate, regardless of whether they’re adding a migration. It’s something I see pretty frequently.

I’m not sure that would fix it entirely because there’s other things that cause differences between two developers schema files being generated.

I do agree that a fix for this issue here would have a big impact across the ecosystem.

Generally what I do is simply not check-in the schema.rb file unless I have made field changes. This is preferred often, as it means you need to force yourself to examine your git commits carefully instead of just using git add . which I think is a good practice.

There’s not a ton of evidence that column order can affect performance, but there are definitely cases - MyISAM tables with many varchar columns, for instance, will take longer to retrieve columns that are later in a row:

How column order affects query performance in MySQL at EXPLAIN EXTENDED (YMMV, I haven’t performed this experiment myself)

If this is added, it should be something users can switch off.

—Matt Jones

Agreed, and am personally -1 on this, as it removes information from the schema file.

Instead, how about a task/tool that will update a developer's database to match the schema file?

How about some sort of normalize_schema option that could be turned off if required? I can’t imagine that all that many developers are taking advantage of specific column ordering. For one thing, PostgreSQL doesn’t allow you to reorder columns (without going to a whole lot of trouble).

The constant non-meaningful changes to the schema.rb file seem like a distraction that end up masking what might be important changes.

Anyone on the Rails Core team want to chime in whether a PR like this might be accepted?

— Matias

With all of these threads about schema.rb format - would it just be easier to allow you to specify your own formatter? Have something that responds to format_for(table, columns) or something to that effect? The issue here is that everyone is going to want something different from that file.

+1 on a DIY format. And I wouldn’t justify it strictly on source control: I’d like it for other reasons too. Maybe a config/schema_format.rb ?

+1 on allowing control over formatting, there’s been many times over the years on various projects when schema.rb has flapped for spurious reasons, it would have been good to have had control over it.

– Chad

+1

What we are currently doing is remove db/schema.rb from source control but it makes us to run every migration on the CI server, what became slow as the project grows.