A Go Database Migration CLI Tool
I just finished my first real project with Go and so far have really enjoyed this programming language. It’s called “gograte” (go + migrate), its a simple database migration CLI tool. For the longest time I’ve focused mainly on JavaScript/TypeScript and web dev stuff, and I finally decided it's time to learn a new language and level up my programming skills. Go seemed powerful and easy enough to learn, and at this point in my software developer journey I’m much more interested in backend stuff. I want to puke at the thought of having to write react components or design a UI, I’ll leave the frontend code to AI at this point (Gemini is 3 pro is a BEAST).
Many times I've had the problem of wanting to clone an entire sql schema from a remote database to my local db and it's always a pain. I use Datagrip for my database migration and it works great, I just needed an excuse to build this tool. I wanted to have a command to run in the terminal to do it quickly and this was a perfect opportunity to build a Go CLI program. Working on projects like this is the best way to learn in my opinion.
The main idea is there is a "target" and "source" database. The source database is where all table schemas sit, and the target is the database to add these new schemas to. This program features two main commands:
-
replace
Replace will delete everything in the "target" database (deleting all tables and columns within) and replacing with the current table/column structure being used on the "source" database. All queries executed are wrapped in a transaction so if anything goes wrong nothing will be messed up.
-
diff
Diff will show the new, removed, and existing tables between the two databases. New will be tables that exist in the source but not the target, removed will be tables that exist in target but not source, and existing will show changes in a table's column that exists in both databases.
What I like about GO
- Multiple return values from a function is awesome. The pattern of returing an error along with the actual value is a really concise way to error handle. There's something that makes me very confident in the code I'm writing that I've never felt with JavaScript.
- It is so easy to read and write. It just feels so simple due to the small set of keywords for the language.
- Importing packages and hosting your Go codebase on GitHub accessible for anyone to download is cool.
- Executable files that have all the dependencies baked in. No node_modules or bloat to the final program, just a single file. So easy to throw into a docker container and run something in the cloud.
What I don't like about Go
- The reference date of January 2nd, 2006 being used to format date strings is confusing at first and I can see how new Go developers might not get why this is important. I cannot begin to explain the confustion I had whlile working with a date for my first time not understanding the significance of this date or why I needed to use it.
- I HATE how Go doesn't have a ternary operator. I use ternary operators all the time in JavaScript. Having an ugly if/else bracket when I could have just done it in a single line is so frustrating.
- The struct tags format is so ugly. I have no idea if I formatted it correctly until the program runs and then gets mad at me. Why does it need to be surrounded in tick marks? So dumb.
- The whole concept of public vs private. Having to capitalize a function or struct that I want to use outside of a package is just stupid. I would like to have an explicit “public” modifier or a "export" declaration to clearly show something is being used elsewhere.
So far I’m loving Go and plan to work on other projects in the future with it. You can find the source code for this project here