5 ms·
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)
by snprbob86 15y ago
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) 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.
- jarin 15y agoWell, yeah I totally agree. I didn't want to start a flame war :)
- jarin 15y agoMission failed.
- fernandotakai 15y agoI 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.
- snprbob86 15y ago> 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.
- fernandotakai 15y agoI don't know, but i think that looking at models/yourmodel.py is easier. But well, this is me (and also, i came from a hibernate/spring background). And for 'newbies', it's more intuitive to look for a class model than to look for sql schema.
- masklinn 15y ago> 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. They're just written for you by the migration tool. One thing I'm sure you'll agree with is that computers are good at grunt, non-creative work. If the computer can write a migration, why not let it do so? > 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. Hogwash.
- jarin 15y agoI would argue that manipulating your database schema is creative work.
- snprbob86 15y agoFor 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.
- 15y ago
- awj 15y agoJust 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.
- moe 15y agoAt 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.
- snprbob86 15y agoHe'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....
- moe 15y ago1) 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.
- snprbob86 15y agoWhen 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)
- moe 15y agoYes, that's what everybody refers to when they quickly need to look up a field. However, having to look in two places to understand your model is a bit cumbersome, isn't it? Especially when complex associations come into play and you have to resolve the rails identifier magic in your head... And then there's the question of why you should have to refer to a cached copy of your schema when you could just spell it all out in one place.
- jarin 15y agoIf remembering attribute names is your concern, you can use an IDE or vim plugin for autocomplete, or just use annotated_models to add/update the schema down at the bottom of your model files on every db:migrate: https://github.com/openteam/annotated_models https://github.com/openteam/annotated_models
- moe 15y ago