I recently saw a tweet from someone complaining about Visual Studio database projects:
Visual Studio db projects – sounds like a decent idea until you discover it was designed by people who’ve never built a real-world db app.
It reminded me of our own experience with this technology. We tried using it,
but ultimately chose db migrations instead. And while there were many reasons not to choose it, probably the most compelling one was that its approach
was too magical.
What Exactly Do You Mean by “Magical”?
Solutions of the “magical” variety go out of their way to hide (obfuscate?) the underlying implementation. They present the developer with
a Faustian bargain: I’ll make it easy for you to get things done so long as you don’t question how I work.
VS db project is a classic case study in magical solutions. Its job is to help you manage database changes and it does that by comparing your current schema (i.e., development)
against some baseline version (i.e. production). That comparison results in a delta file, which you could then apply to the baseline.
The problem is that it’s very difficult to predict with certainty what will be in the delta file (especially on projects with many database changes).
So, to use Visual Studio’s db project, you just have to trust that it always does the right thing. You have to believe in magic.
Ok, But What’s Wrong With Magic?
Well, good devs* don’t like magic. They want to understand exactly what’s happening under the hood. They want to know how the machine got from point
A to point B. Most importantly, they want to be in control of their code (instead of the other way around).
Good devs also know that magic comes at a cost. That cost is paid when things don’t work exactly as you expected. Suddenly, you have to dig through
a maze of your framework’s abstractions to understand what went wrong.
This is why db migrations are so dev friendly. There’s no mystery here: sequentially numbered files are applied, one by one, to the database.
You can see exactly what changes are being made at each step, you can see exactly what version your database is currently at, etc. No magic.
Yes, But Isn’t Everything Magical to Some Extent?
I realize that any abstraction could be considered magical. For instance, a compiler is magical: you blindly rely on it to transform your source into a binary executable.
The thing is, for certain abstractions the tradeoff between transparency and magic makes sense. Sure, you could figure out what exactly the compiler
is doing behind the scenes, but why would you want to? (other than to get Vietnam-style flashbacks from your undergrad compilers course).
Furthermore, it’s not always obvious when that tradeoff makes sense. Take CoffeeScript.
a compelling case that the cost of obfuscation is too high.
* By the way, I don’t think this is true for all devs. In my experience, mediocre / bad devs are usually a lot more willing to accept magical solutions.
You may also like