Blog
Psst: Want a Pretty + Polished + Powerful SQL IDE for Your Terminal?
Steve Swoyer | 15 November 2024
Fun Package Fridays is a series where we ask members of the Flox team to share fun and perhaps not-so-well-known tools and utilities you can find in the Flox Catalog, powered by Nix. Today's edition comes from staff writer Steve Swoyer, who describes himself as a recovering data practitioner.
When my friend Mark Madsen messaged asking, βu heard about this SQL TUI tool called harlequin? does ur π±alog have this π₯?β, my first response was: βWhatβs a TUI?β
Seriously, though, once I looked into what Harlequin does, I was hooked. As for Markβs second question, I didnβt for a second doubt the answer: βItβs in there. It has to be in there.β
Harlequin is, indeed, in there. And Markβs questions set the stage for this weekβs installment of Fun Package Friday(R)(TM), featuring Harlequinβstraight from the Flox Catalog. Read on to find out how you can get and share a portable, reproducible SQL editor environmentβwith no containers or VMs!
Getting It
Letβs kick things off by installing Flox. If you havenβt yet done this, you can easily download, install, and play along at home. Second, letβs grab Floxβs PostgreSQL example environment. Weβre going to need a database to query against, and (as Han Solo might put it) PostgreSQLβll do nicely.
The flox pull --copy
command makes a local copy of the remote postgres
environment, which is hosted on FloxHub. Weβre copying postgres
rather than activating it as an ephemeral remote environment (using flox activate -r
) because we need to add harlequin
and other packages to it. The postgres
environment is managed (by Flox), so itβs locked; we can't add packages to it, change environment variables, or add new services. The reason for this is so everybody who runs it using flox activate -r
always gets exactly the same version.
OK, now weβve got to install Harlequin and its PostgreSQL adapter. Weβll install a compatible Python version, too, just to rule out the possibility of dependency conflicts with our local Python installation.
Flox makes this easy enough:
Awesome. Now letβs light this candle! Weβll start the postgres
environment using the flox activate -s
switch, which tells Flox to spin up any services defined in its declarative manifest.
This puts me into a subshell where I can access and use the software Flox just installed. Now Iβm ready to run Harlequin!
To get right to the fun part, Iβll skip the steps where I create and populate my database. If youβre interested in what these involved, jump ahead to Housekeeping Notes.
Using It
We'll use Harlequin to query against a database containing information about The Simpsonsβstuff like episode names, numbers and descriptions, guest stars, directors, writers, and so on.
To run Harlequin, all youβve gotta do is plug the defaults from the Flox PostgreSQL environment into a connection string and run it in your terminal:
(Programming note: You could easily alias this connection string in your Flox environmentβor have it run automatically when you activate your environment.)
As you can see, Harlequin not only has an extremely pretty terminal UI, itβs got an oh-so-pretty terminal UX, too. For one thing, it supports point-and-click mouse interaction, something that still amazes me whenever I encounter it; for another, it provides command- and keyword-completion capabilities, as shown below.
This isnβt just one of the prettiest terminal tools Iβve ever used, itβs one of the most useful, too.
The idea with this first query is just to verify that my database actually works. So Iβm starting with something basic, like which episodes comprise Season 2 of The Simpsons.
Booyah! It works! Now Iβll try something just a mite more advanced: in which episode did the immortal Richard Starkey guest star?
How about the White Stripes? I know Jack White and Meg White guest-starred in an episode, although I canβt remember if they were credited as the White Stripes. Which episode was it?
Now that I think on it, The Simpsons sure had scads of guest stars. How many episodes featured multiple stars? Searching for this on IMDB is β¦ well, I have no idea how Iβd do that using its basic search interface.
With our PostgreSQL Simpsons database, itβs easy:
One last query, just to dust off my SQL: can we list episodes in which specific guests starred together?
Yes we can!
Sharing It
I can also use Flox to easily share what Iβve created with β¦ anybody, including my friend Mark, whoβas an old-school software engineer-turned-data-architectβis reflexively skeptical of any technology promising to do everything Flox does. I can either push my postgres
repo to GitHub or use the flox push
command to push it to FloxHub. Because Mark hitherto has resisted the Call of Flox, Iβll opt for the GitHub method.
First Iβll git init
a repo in my project directory, then Iβll run git add .
and git commit
. Next, Iβll use gh
to create a corresponding GitHub repo and connect it to my local repo. Finally, Iβll git push
my Floxified repo to GitHub. Sound familiar? It should: itβs the same workflow we use whenever we create a new GitHub repo!
If I really want to make things easy, I could add my get-floxxed.sh
script to my GitHub repo. This automatically downloads and installs the latest version of Flox. From Markβs perspective, all heβd need to do is git clone
my repo and run get-floxxed.sh
. I could even configure this script to prompt him:
βDo you want me to create a βharlequin` alias you can use to activate this environment?β
If Mark were already an inveterate Flox user like me, this would be even easier. I could just tell him to run...
...and heβd get a portable, reproducible version of my environment.
Making It Your Own
I built extra packages (like jq and jless) into my version of the postgres
environment so Mark has everything he needs to transform and load data into his local PostgreSQL instance. I also added some logic that automatically creates and activates a Python virtual environment (venv), just in case he needs to do some of this stuff using Python. In addition, the environment now looks for and parses a requirements.txt
file and, if it finds one, automatically installs any Python dependencies.
In the profile
section of my postgres
environment's manifest, I 've aliased harlequin
to the correct database connection string, so connecting to the local PostgreSQL database instance is as simple as can be. Mark has a massive collection of scholarly PDFs heβs always struggling to organize, so I went ahead and created a mock data model for importing, managing, and searching metadata from these. He can use Harlequin to perform this entire process, from running the DDL that creates database objects, to dropping the existing databases (if he wants to), to populating the researchpapersdb
database itself.
Speaking of which, in the screenshot below, Iβve already run CREATE DATABASE ResearchPapersDB;
, which defined the database of the same name that you see in Harlequin's left-hand pane. Now I've highlighted USE ResearchPapersDB;
and can run that command by clicking the Run Selection
button. From there, creating the tables and other schema objects defined in the DDL is as easy as highlighting each statement in Harlequinβs query editor and clicking Run Selection
. A SQL guru like Mark should have no problem with this!
Housekeeping Notes
I sourced the dataset for my Simpsons database from this GitHub repo. Itβs a little dated, and itβs missing some essential guest stars (Hello!? The Ramones!? Thomas Pynchon?! Johnny Cash?!) but itβs nicely formatted JSON and working with it was a pleasure. My thanks to its creator!
I did have to do some prep work on this dataset, but this wasnβt an altogether un-fun activity. The quotes (β
and β
) in the JSON werenβt escaped, so I needed to fix that. And I also had to convert the dataset's JSON objects into a newline-delimited format so I could get PostgreSQL to process it. On the whole, pretty standard, really.
Once this was done, I was able to delegate the following operations to PostgresSQLβs database engine:
- Import JSON data directly as JSONB into a raw/temporary PostgreSQL table;
- Transform the JSONB and then load the resulting tabular structure into a relational table.
Believe it or not, this was actually fun!
This has been Fun Package Friday
So thatβs Harlequin. Pretty neat, huh? Pretty and neat. Even better, Harlequin isnβt just βfreeβ as in F/OSS, but βfreeβ as in free of charge. This last is amazing! To be honest, I would happily pay for a tool like this. Iβm both humbled and amazed by the quality of the open source software that people like Harlequinβs maintainer and the community supporting it gift to us.
Happy Hacking!