Live data from Hacker News

Reversible Migrations in Rails 3.1

edgerails.info

11–20 of 35 posts

Re: Reversible Migrations in Rails 3.1

#11
post #4

Earlier quoted context omitted.

That probably won't happen (anytime soon at least), because Rails takes the approach of generating your model attributes based on the table fields, not Django's (equally valid) approach of declaring the model attributes on the model and then generating the migrations based on that. Personally, I prefer the Rails way of doing it, since it keeps my model files cleaner and avoids ambiguity (to me) when adding/removing/c…

I too prefer Rail's approach. However, I disagree that Django's approach is equally valid :-) I've written about this before, but here's the short version: 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. 3) Inclu…

Just to be contrary:

> 1) The database holds the authoritative schema. You shouldn't duplicate it in your code.

I care about the authoritative data model, which is slightly different from the authoritative schema. Beyond that, I don't edit the database schema. There are many cases where I'm happier to have a complete data model in one location versus (at least) two and needing to mentally parse how rails reacts to the database schema.

> 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway.

In case you didn't notice, the automatic migration was happening through a --auto command line flag. Manual migrations exist, and are the default.

> 3) Including column declarations in your model forces the database's strong typing system onto what should be plain old Ruby/Python objects. The result is ineffective domain objects.

Why should these be plain old Ruby/Python objects? ActiveRecord already is a pretty extensive DSL for relating objects to database tables. Does including attribute descriptions really make it "not a plain old Ruby object" when we already have well developed support for field validation and relationship declarations?

That said, I don't think the auto migrations are good idea. You're right, eventually you'll want to do a manual migration. At that point it's painfully easy to create a situation where your manual migration depends on properties of your model that have since changed. It's a problem akin to using your AR classes to help manipulate data in a migration. We have a point in our migration history we simply cannot restart from because it uses a model class that has since been removed.

Re: Reversible Migrations in Rails 3.1

#12

Earlier quoted context omitted.

I too prefer Rail's approach. However, I disagree that Django's approach is equally valid :-) I've written about this before, but here's the short version: 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. 3) Inclu…

> The database holds the authoritative schema. Why? > You shouldn't duplicate it in your code. If the database does not hold the authoritative schema, you're not duplicating anything. > What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. Of course, but it's not like the generated migrations are special. The…

I would argue that manipulating your database schema is creative work.

Re: Reversible Migrations in Rails 3.1

#13
post #11

Earlier quoted context omitted.

I too prefer Rail's approach. However, I disagree that Django's approach is equally valid :-) I've written about this before, but here's the short version: 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. 3) Inclu…

Just to be contrary: > 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. I care about the authoritative data model , which is slightly different from the authoritative schema . Beyond that, I don't edit the database schema. There are many cases where I'm happier to have a complete data model in one location versus (at least) two and needing to mentally parse how rails reacts to…

At that point it's painfully easy to create a situation where your manual migration depends on properties of your model that have since changed.

I don't understand the situation you're describing. The migration-files, once created, are independent from the model. That means you can re-run the chain at any point in time, regardless of what your current model looks like.

Having an auto-generator for the migration files doesn't change that.

Re: Reversible Migrations in Rails 3.1

#14

Earlier quoted context omitted.

I too prefer Rail's approach. However, I disagree that Django's approach is equally valid :-) I've written about this before, but here's the short version: 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. 3) Inclu…

> The database holds the authoritative schema. Why? > You shouldn't duplicate it in your code. If the database does not hold the authoritative schema, you're not duplicating anything. > What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. Of course, but it's not like the generated migrations are special. The…

For one, the database is the only place where the entire schema is maintained. This includes indexes, constraints, relationships, etc. If I need to go add an index to a production system, that is not captured in the code. I should, however, dump the schema to a .sql file and check that in, but that's still separate from the model's .py file, so that file can't be considered authoritative.

More importantly, the database exists without the application. The application does not exist without the database. You might inherit a database/schema from someone else. And once your application grows, the database will surely have additional clients: you might want to access it via SQL directly or from some other language.

> One thing I'm sure you'll agree with is that computers are good at grunt, non-creative work.

It's been proven that you can reliably wrap each row in an object and each column's field with a getter/setter pair. It's easy. Totally non-creative, grunt work. That's what Active Record does.

Migration generation via diffing schemas? That's a much harder, in fact provably intractable problem! There are many ways to get from A to B. If you're going to leave it to a computer to generate either migrations or classes with getters and setters, I'd much prefer the computer do the getters/setters.

Re: Reversible Migrations in Rails 3.1

#15

Earlier quoted context omitted.

I too prefer Rail's approach. However, I disagree that Django's approach is equally valid :-) I've written about this before, but here's the short version: 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. 3) Inclu…

I have to say that i prefer the Django/sqlalchemy way. I know that i'm probably duplicating code, but with this way, i don't have to look at the database to know which properties a model has, i just have to go to the .py file. Also, i can use migrations as well to make sure the database is with the right version.

> i don't have to look at the database to know which properties a model has

I just pop open db/schema.rb and then search for where the users table schema is described. This .rb file is automatically generated. In production systems, I actually configure it to use db/schema.sql which stores the SQL schema instead of the Ruby schema, since my production database has indexes that Rail's migrations can't describe directly.

Or even more directly:

  psql -c '\d users'
Which I typically run from vim:

  :!psql -c '\d users'
And that just prints out the description of the table for me.

Re: Reversible Migrations in Rails 3.1

#16
post #11

Earlier quoted context omitted.

I too prefer Rail's approach. However, I disagree that Django's approach is equally valid :-) I've written about this before, but here's the short version: 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. 3) Inclu…

Just to be contrary: > 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. I care about the authoritative data model , which is slightly different from the authoritative schema . Beyond that, I don't edit the database schema. There are many cases where I'm happier to have a complete data model in one location versus (at least) two and needing to mentally parse how rails reacts to…

> I care about the authoritative data model

Me too, but the truth about the world is that all inherit complexity is accompanied by incidental complexity :-/ You've got a database, you need to respect it's existence.

> mentally parse how rails reacts to the database schema

It's hilariously straightforward in 99% of cases:

For each column, a getter and setter are created. The getter directly calls read_attribute and the setter calls write_attribute. Those two methods do standard string/integer/date/etc primitive conversion. What's there to map in your head?

> Manual migrations exist, and are the default.

Right, that's the point I'm making. They should be the default. I'm also saying that I shouldn't have to write a migration AND maintain some declarations in the python file.

> it's painfully easy to create a situation where your manual migration depends on properties of your model that have since changed.

Oh, I've made this mistake. Since then, I stopped referencing my models in my migrations. I just run raw SQL (or the shorthand Ruby functions for the most common cases). As a result, my migrations are waaaay faster (batch updates rather loops, etc) and I've never had this problem since.

Re: Reversible Migrations in Rails 3.1

#17
post #13
post #11

Earlier quoted context omitted.

Just to be contrary: > 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. I care about the authoritative data model , which is slightly different from the authoritative schema . Beyond that, I don't edit the database schema. There are many cases where I'm happier to have a complete data model in one location versus (at least) two and needing to mentally parse how rails reacts to…

At that point it's painfully easy to create a situation where your manual migration depends on properties of your model that have since changed. I don't understand the situation you're describing. The migration-files, once created, are independent from the model. That means you can re-run the chain at any point in time, regardless of what your current model looks like. Having an auto-generator for the migration files…

He's making the same mistake I once made: Trying to use his models from the migrations.

I'd really like to see Rails raise a deprecation warning if a model gets dynamically loaded by a migration....

Re: Reversible Migrations in Rails 3.1

#18
post #4

Earlier quoted context omitted.

That probably won't happen (anytime soon at least), because Rails takes the approach of generating your model attributes based on the table fields, not Django's (equally valid) approach of declaring the model attributes on the model and then generating the migrations based on that. Personally, I prefer the Rails way of doing it, since it keeps my model files cleaner and avoids ambiguity (to me) when adding/removing/c…

I too prefer Rail's approach. However, I disagree that Django's approach is equally valid :-) I've written about this before, but here's the short version: 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. 3) Inclu…

1) The database holds the authoritative schema. You shouldn't duplicate it in your code.

That's nonsense, your application implies the authoritative schema as it relies on a given set of model fields to exist. More importantly any given version of your application may imply a different schema.

Artificially detaching the schema from the code only causes problems and adds pointless complexity to the overwhelming majority of applications (which don't share the database with anything else).

Having to reach for irb or psql only to figure out what fields exist on a given model is backwards. Having to manually craft migrations with proper indexes, keys and constraints to match the separately defined validations and associations is completely ass-backwards.

Re: Reversible Migrations in Rails 3.1

#19
post #18

Earlier quoted context omitted.

I too prefer Rail's approach. However, I disagree that Django's approach is equally valid :-) I've written about this before, but here's the short version: 1) The database holds the authoritative schema. You shouldn't duplicate it in your code. 2) What if you want to do something more complicated, like split the values in one column into two columns? You're going to need support for manual migrations anyway. 3) Inclu…

1) The database holds the authoritative schema. You shouldn't duplicate it in your code. That's nonsense, your application implies the authoritative schema as it relies on a given set of model fields to exist. More importantly any given version of your application may imply a different schema. Artificially detaching the schema from the code only causes problems and adds pointless complexity to the overwhelming majori…

When a migration runs, the schema.rb file is regenerated. This way, each checkin contains a complete snapshot of the schema that goes with that code.

(side note: I think that schema.sql should be the default, not schema.rb)

Re: Reversible Migrations in Rails 3.1

#20
post #13

Earlier quoted context omitted.

At that point it's painfully easy to create a situation where your manual migration depends on properties of your model that have since changed. I don't understand the situation you're describing. The migration-files, once created, are independent from the model. That means you can re-run the chain at any point in time, regardless of what your current model looks like. Having an auto-generator for the migration files…

He's making the same mistake I once made: Trying to use his models from the migrations. I'd really like to see Rails raise a deprecation warning if a model gets dynamically loaded by a migration....

Every Rails developer makes that mistake once (well, hopefully not more than once). What I'd really like to see next is a way to version seeds.rb.
Post reply on HN