Live data from Hacker News

Atlas – Terraform but for Database Migrations

atlasgo.io

11–20 of 92 posts

Re: Atlas – Terraform but for Database Migrations

#11

Is it just me or I hate to learn new configuration languages that may disappear in no time after having invested time and effort learning them? Not just the syntax but all the nuances and the configuration options that come with it. If it was a migration tool using ANSI SQL as a configuration language I would have been happy to try it out. You can probably achieve the same declarative style by using SQL and running a…

It will be interesting to see if this approach is defensible and better than other strategies, but I’m not holding my breath.

Learning HCL for Terraform is one of the worst parts, IMO. It’s like Dropwizard config language made a baby with JSON-but-not-quite-JSON.

For now, I’m going to hold back on this particular time investment.

P.s. Is this really another project called “Atlas”? The number of times I’ve encountered projects sharing this name over the course of my career is just depressing. Too generic to be any degree of informative or unambiguous, definitely wish it was called Schemmaform instead, a way better name, and took me all of 5 seconds to come up with.

Re: Atlas – Terraform but for Database Migrations

#12

I'll never be comfortable with any tool for that automatically generates schema changes, as I'm just never sure at what point it decides to delete parts of my prod db. All of my migrations are dumb DDL statements rolled up into a version. I know exactly what the final state is as it gets run and used when integration testing, staging etc. It's boring but pretty bulletproof. I can rename a table and be confident it'll…

I feel the same way. I'd prefer to program an SQL database in SQL.

What I personally do these days is to write migrations as normal (sql files for the "up" and "down" steps), and then have a `go generate` step that creates a randomly-named database, applies each migrations, and dumps the schema into a file that gets checked in. A test assures that the generated content is up to date with the rest of the repository. This gives you 3 things:

1) PR reviewers can see what your migration does to the database in an easy-to-read diff. (A tiny bit of regexing needs to be done to make PostgreSQL dumps compatible between machines; it puts the OS name and the build time in there.)

2) You have the full database schema in an easy-to-read form. I open the SQL dump all the time to remind myself of what fields are named, what the default values are, etc.

3) Unit tests against the database are faster. Instead of creating a new database and applying 100s of migrations, you just apply one dump file. Takes milliseconds.

In general, I think that database migrations are fundamentally flawed. The database schema and the application should have a schema version that they expect, and rules for translating between versions. That way, you could upgrade your code to something that reads and writes "version 2", but understands "version 3", and then apply the database migration at your leisure, and update the code to start writing "version 3" records. But, nobody does this. They just cross their fingers and hope they don't have to roll back the migration. And honestly, I don't think I've ever had to roll back a migration, because they're so scary that you test it a billion times before it ever makes it to production. But, that testing-a-billion-times comes at the cost of writing new features, and the team that only tests it 999 million times no doubt has a horror story or two.

Re: Atlas – Terraform but for Database Migrations

#13
In my experience, this sort of thing breaks down when you have a large production database that requires carefully crafted migrations to avoid affecting the existing system and taking too many locks.

For example, with Postgres some indexes have to be performed with "CREATE INDEX CONCURRENTLY" or "DROP INDEX CONCURRENTLY", which cannot be done inside a transaction. (Also, a "CREATE INDEX" like this can fail halfway and leave behind an invalid index that must be manually deleted.) Whether this must be done with "CONCURRENTLY" or not isn't something the tool can know.

In some cases, a change must done in multiple steps. For example, if you change a column from "NULL" to "NOT NULL", you have to provide a default value. Updating the database with a default value can in fact be a huge operation that might even have to be done in multiple stages to avoid locking rows for too long. There's no way to easily express this in a DSL. M

Then there's the database support. A tooo like this needs to support a huge range of features. Postgres has extensions (CREATE INDEX ... USING), special index operator classes, functional indexes, partitioning, and so on. I've seen many ORMs or SQL adapters (ActiveRecord/ARel, Squirrel, Goqu, Sequelize) try to be smart with how they let you build SQL from high-level code, but they all fail to cover all cases. (Recently I needed to do "ORDER BY CASE ... END" and was using Goqu, which has support for case expressions, but did not support sorting on them.)

So while a tool like this might be good when you're just starting out, for a "real" app you want to avoid this sort of automation, because the tool is almost certainly not going to be smart enough.

I'm a fan of non-magical tools that let me just write SQL migrations, like dbmate and Goose, because that gives me full control. Having a tool to magically figure out the diff isn't super helpful, because I really need to know the diff myself when writing the migration, in order to make it predictable. It's simply more convenient to specify the order yourself.

Re: Atlas – Terraform but for Database Migrations

#14

Earlier quoted context omitted.

You might find something like Hasura interesting. https://hasura.io/ It is a GraphQL server that sits on top of your Postgres DB and the schema reflects the table schema. It's quite powerful right out of the box. If you combine that on the front-end with Apollo and a Typescript types code generator, you end up with strong typing all the way from your database to the front-end.

I went with Prisma + Nexus + Pal.js + Apollo, which was probably at least two layers too complex. I'm looking, still, for an all-in-one solution to this, though I do need more control over my queries/mutations than what Hasura would give me.

When faced with this problem, I wound up using normal SQL migrations to set the DB state, sqlc to generate the SQL boilerplate (https://sqlc.dev/), and I wrote a little tool to generate the HTTP handler boilerplate for these tables.

Not all-in-one, but this approach has been really effective in a large codebase.

Re: Atlas – Terraform but for Database Migrations

#15
I wish people would explain why they created their project and what their pain points were with existing alternatives. All I can find is "Contrary to existing tools, Atlas intelligently plans schema migrations for you, based on your desired state."

What's so bad about writing an explicit migrations using something like Flyway? I'm a fan of declarative configuration for the most part but it doesn't seem that beneficial here to me. Sure, using it to modify the schema to the desired state is fine from just the schema perspective. But there is also data you have to worry about. Like someone else stated, the rename example is probably the most trivial example. How would the tool know if I wanted to delete one column and add another or if I wanted to rename the column?

Another more complicated example is what if I had a column called created_at that stored a string and I wanted it to store a date instead. How would atlas know that just by changing the type? I might want it deleted and recreated. But if not, how would it know what format I stored the string in and how to parse it?

For the rename problem, each column could have it's own id so if the id doesn't change it's a rename. Or it could ask while running the migrate command and then store those answers somewhere to be used when deploying to production which seems like a pain. Something like that might work for changing the data type too. You have two columns with the same name and different ids. The new column could have something to specify to transform the data from the old column.

(I know it's a terrible idea to change the data type of a column in production, but the same idea applies if you want to copy the data converted to a new type to a new column, get your production code using that new column, then delete the other column.)

Either way, this doesn't seem to by much over the classic migration approach. You still have to think about how the data is going to move or be manipulated. And with the classic approach they generate a schema so you can see the final state of your database and make sure it's what you want. With the atlas approach you have to approved the planned migration which is basically the same thing as making sure the schema generated is correct using the classic imperative approach.

Re: Atlas – Terraform but for Database Migrations

#16
Agree with general sentiment that creating a DSL/HCL like thing to essentially represent DDL commands seems less than ideal I wouldn’t want to be the author on the hook for never ending sql functions etc, you’d want a good escape hatch, same pain as hcl. But for a tool like this to add value (just like terraform) it’s got to understand the relationship graph, properties of resources etc.

I’m a big believer in manual simple sql migrations via flyway or similar, but if you got this working in theory and built the features it could do a better job on average than non expert humans, it could enforce patterns / naming / conventions / indexes etc. Could do with sql migrations too but would be more difficult as it wouldn’t have the full declared model.

Re: Atlas – Terraform but for Database Migrations

#18

Earlier quoted context omitted.

You might find something like Hasura interesting. https://hasura.io/ It is a GraphQL server that sits on top of your Postgres DB and the schema reflects the table schema. It's quite powerful right out of the box. If you combine that on the front-end with Apollo and a Typescript types code generator, you end up with strong typing all the way from your database to the front-end.

I went with Prisma + Nexus + Pal.js + Apollo, which was probably at least two layers too complex. I'm looking, still, for an all-in-one solution to this, though I do need more control over my queries/mutations than what Hasura would give me.

(Apologies for going off-topic)

I am working on a solution to simplify this piece of the puzzle and seeking feedback for an early version of the solution.

Please DM me (email in profile) and we can set something up.

Re: Atlas – Terraform but for Database Migrations

#19

I'll never be comfortable with any tool for that automatically generates schema changes, as I'm just never sure at what point it decides to delete parts of my prod db. All of my migrations are dumb DDL statements rolled up into a version. I know exactly what the final state is as it gets run and used when integration testing, staging etc. It's boring but pretty bulletproof. I can rename a table and be confident it'll…

I feel the same way. I'd prefer to program an SQL database in SQL. What I personally do these days is to write migrations as normal (sql files for the "up" and "down" steps), and then have a `go generate` step that creates a randomly-named database, applies each migrations, and dumps the schema into a file that gets checked in. A test assures that the generated content is up to date with the rest of the repository. T…

I thought the established wisdom is to make schema migration compatible with both the old app and the new app, whenever it is possible? E.g. you can safely add a nullable column, and it shouldn't trip up the old app nor the new app, unless you are using some crappy ORM that does "SELECT *", or you are on an older MySQL version that may take hours/days/weeks to rewrite the whole table just to add a nullable column.

https://github.com/fabianlindfors/reshape, on HN front page a couple weeks ago, has some nice tricks to help with the incompatible cases.

Re: Atlas – Terraform but for Database Migrations

#20
post #6

When documenting a migration tool, show an example of renaming a column before working on the logo.

This is always my only question when the salesperson is finished pitching some new provisioning or identity management tool. “Can I rename users when they change their name?” “Does that happen that often?” “Half the staff here are female and may change their surname when they get married.” “Err.. umm… I think that’s a work in progress.” “It’s fundamentally impossible with your architecture and it’s the thing that we…

Which identity management tools have you had in mind btw?
Post reply on HN