First Quarter Workshops, Code Sessions, & Twitch Streaming Schedule

I present, the details for upcoming workshops, sessions, and streams for the first quarter of 2021. This quarter includes January through March. In late March an updated list of new content coming and existing context continuing will be posted then.

Thrashing Code Channel on YouTube for the VODs and VLOGs.

Thrashing Code Channel on Twitch for the live streams.

Hasura HQ on Twitch and YouTube too.

Composite Thrashing Code Blog where I put together articles about the above content plus list events, metal, and a lot more. Which I also mirror here for those that like to read on Medium and also on who like to read there.


Workshops are 1+ hour long, have breaks, and a mostly a set curriculum. They’ll often have collateral available before and after the workshop such as slide decks, documentation, and often a code repository or two. The following are the scheduled workshops I’ve got for first quarter of 2021.

January 28th @ 12:00-14:00 PT Relational Data Modeling for GraphQL – This will be a data modeling workshop focused around getting a GraphQL API up and running built around a relational data model. In this workshop I’ll be showing how to do this using dbdiagramJetbrains DataGrip, and the Hasura API & CLI tooling. The ideas, concepts, and axioms I lay out in this workshop are not limited or tightly coupled to these tools, I used them simply to provide a quick and effective way to get much further into concept and ideas, and move beyond this to actual implementation of concept and ideas within the workshop. Thus, the tools aren’t must haves, but they will help you follow along with the workshop.

January 20th @ 14:00-15:00 PT Introduction to GraphQL – This workshop will take you through the architectural and programmatic use of GraphQL. In the first part of this workshop I’ll take you through an architectural tour of how, where, why, and what options exist for GraphQL API Servers. In the second part of the workshop we’ll spin up a Hasura API Server, import some data, and work through various query examples with GraphQL. Wrapping up this workshop we’ll then take a look at several GraphQL Drivers for the various language stacks out there like .NET, Java, JavaScript/Node.js, Go, and possibly others.

February 17th @ 14:00-15:00 Relational Data Modeling for GraphQL – See above description. This will be a live rerun of the workshop I’ll do, so a new group can join in live, ask questions, and work through the material.

February 18th @ 12:00-14:00 PT Introduction to GraphQL – See above description. Again, a rerun of the above workshop, available to join again or in case you’ve missed a previous session and would like to join.

March 23rd @ 14:00-15:00 Introduction to GraphQL – See above, a rerun of the workshop.

March 24th @ 12:00-14:00 PT Relational Data Modeling for GraphQL – See above, a rerun of the workshop.

One Offs

These sessions will be on a set list of topics that will be provided at the beginning of the event. They’ll also include various collateral like a Github repository, pertinent notes that detail what I’m showing in video.

January 11th @ 10~Noon Join me as I show you how I setup my Hasura workflow for the Go language stack setup. In this session I’ll delve into the specifics, the IDE, and work toward building out a CLI application that uses Hasura and GraphQL as the data store. Join me for some coding, environment setup, workflow, and more. This is a session I’ll be happy to field questions too (as most of my sessions), so if you’ve got questions about Hasura, my workflow, Go, CLI development, or anything else I’m working on join in and toss a question into chat!

February 1st @ 10am~Noon Join me as I broach the GraphQL Coding topic, similar to the one off coding session on January 11th, but this time with JavaScript – a more direct and native way to access, use, and benefit from GraphQL! This session will range from server side Node.js coding to some client side coding too, we’ll talk about the various ways to make calls and a number of other subjects on this topic. As always, dive in and AMA.

Coding Session Series

These sessions may vary from day to day, but will be centered around a particular project or effort, or just around learning something newabout a bit of code, how something works, or other technologically related explorations. An example is in March I’m kick starting #100DaysOfCode which will be a blast! 1 hour a day, for 100 days. What will we learn? Who knows, but it’ll be a blast hacking through it all!

January 15th @ Noon PT Emerald City Tech Talks resume! I’ve got the first episode I’m getting scheduled for the 15th, and then this will occur every month for the first quarter of 2021, and possibly going bi-weekly in the second quarter. The dates so far are January 15th, February 19th, and March 19th all at Noon PT, so it makes for an easy lunch time break viewing. Grab some grub and join me for the latest tech talk, review of gadgetry, and other topics.

March TBD @ TBD, but in March and repeating on weekdays daily! Day 1 and ongoing of #100DaysOfCode! Yup, I’ve decided to jump on the 100 Days of Code Train! The very general scheduling of topics I intend to cover so far goes like this; algorithms, data/storage, vuejs, and then into building a project. Project isn’t decided yet, nor algorithms, nor specific data and storage topics, but that’ll be the general flow. More details to come in late Febuary and early March!

Tuesday, January 12th @ 10:00 PT on Hasura HQ repeating weekly I’ll be putting together a full stack app, learning new parts of doing so, and more using the Hasura tooling along with Vuejs. Join me for some full stack app dev, we’ll be getting – over time – deep into all the things!

Wrap Up TLDR; && Full Schedule

That’s the material I’m putting together for the Thrashing Code and Hasura Channels on Twitch & YouTube, I hope you’ll enjoy it, get value out of it all, or just join me to hang out on stream and in workshops. Give the channel a follow on Twitch, and if you ever miss a live session on Twitch, in ~24 hours or shortly thereafter I’ll have the Twitch stream posted for VOD on the Thrashing Code YouTube Channel, which you can navigate over to and subscribe for all the latest updates for the above videos and more!

Top 3 Refactors for My Hasura GraphQL API Terraform Deploy on Azure

I posted on the 9th of September, the “Setup Postgres, and GraphQL API with Hasura on Azure”. In that post I had a few refactorings that I wanted to make. The following are the top 3 refactorings that make the project in that repo easier to use!

1 Changed the Port Used to a Variable

In the docker-compose and the Terraform automation the port used was using the default for the particular types of deployments. This led to a production and a developer port that is different. It’s much easier, and more logical for the port to be the same on both dev and production, for at least while we have the console available on the production server (i.e. it should be disabled, more on that in a subsequent post). Here are the details of that change.

In the docker-compose file under the graphql-engine the ports, I insured were set to the specific port mapping I’d want. For this, the local dev version, I wanted to stick to port 8080. I thus, left this as 8080:8080.

version: '3.6'
image: library/postgres:12
restart: always
- 5432:5432
image: hasura/graphql-engine:v1.3.3
- "8080:8080"
- "postgres"
restart: always
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:${PPASSWORD}@postgres:5432/logistics

The production version, or whichever version this may be in your build, I added a Terraform variable called apiport. This variable I set to be passed in via the script files I use to execute the Terraform.

The script file change looks like this now for launching the environment.

cd terraform
terraform apply -auto-approve \
-var 'server=logisticscoresystemsdb' \
-var 'username='$PUSERNAME'' \
-var 'password='$PPASSWORD'' \
-var 'database=logistics' \
-var 'apiport=8080'

The destroy script now looks like this.

cd terraform
terraform destroy \
-var 'server="logisticscoresystemsdb"' \
-var 'username='$PUSERNAME'' \
-var 'password='$PPASSWORD'' \
-var 'database="logistics"' \
-var 'apiport=8080'

There are then three additional sections in the Terraform file, the first is here, the next I’ll talk about in refactor 2 below. The changes in the resource as shown below, in the container ports section and the environment_variables section, simply as var.apiport.

resource "azurerm_container_group" "adronshasure" {
name = "adrons-hasura-logistics-data-layer"
location = azurerm_resource_group.adronsrg.location
resource_group_name =
ip_address_type = "public"
dns_name_label = "logisticsdatalayer"
os_type = "Linux"
  container {
name = "hasura-data-layer"
image = "hasura/graphql-engine:v1.3.2"
cpu = "0.5"
memory = "1.5"
    ports {
port = var.apiport
protocol = "TCP"
    environment_variables = {
secure_environment_variables = {
HASURA_GRAPHQL_DATABASE_URL = "postgres://${var.username}%40${}:${var.password}@${azurerm_postgresql_server.logisticsserver.fqdn}:5432/${var.database}"
  tags = {
environment = "datalayer"

With that I now have the port standardized across dev and prod to be 8080. Of course, it could be another port, that’s just the one I decided to go with.

2 Get the Fully Qualified Domain Name (FQDN) via a Terraform Output Variable

One thing I kept needing to do after Terraform got production up and going everytime is navigating over to Azure and finding the FQDN to open the console up at (or API calls, etc). To make this easier, since I’m obviously running the script, I added an output variable that concatenates the interpolated FQDN from the results of execution. The output variable looks like this.

output "hasura_uri_path" {
value = "${azurerm_container_group.adronshasure.fqdn}:${var.apiport}"

Again, you’ll notice I have the var.apiport concatenated there at the end of the value. With that, it returns at the end of execution the exact FQDN that I need to navigate to for the Hasura Console!

3 Have Terraform Create the Local “Dev” Database on the Postgres Server

I started working with what I had from the previous post “Setup Postgres, and GraphQL API with Hasura on Azure”, and realized I had made a mistake. I wasn’t using a database on the database server that actually had the same name. Dev was using the default database and prod was using a newly created named database! Egads, this could cause problems down the road, so I added some Terraform just for creating a new Postgres database for the local deployment. Everything basically stays the same, just a new part to the local script was added to execute this Terraform along with the docker-compose command.

First, the Terraform for creating a default logistics database.

terraform {
required_providers {
postgresql = {
source = "cyrilgdn/postgresql"
required_version = ">= 0.13"
provider "postgresql" {
host = "localhost"
port = 5432
username = var.username
password = var.password
sslmode = "disable"
connect_timeout = 15
resource "postgresql_database" "db" {
name = var.database
owner = "postgres"
lc_collate = "C"
connection_limit = -1
allow_connections = true
variable "database" {
type = string
variable "server" {
type = string
variable "username" {
type = string
variable "password" {
type = string

Now the script as I setup to call it.

docker-compose up -d
terraform init
sleep 1
terraform apply -auto-approve \
-var 'server=logisticscoresystemsdb' \
-var 'username='$PUSERNAME'' \
-var 'password='$PPASSWORD'' \
-var 'database=logistics'

There are more refactoring that I made, but these were the top 3 I did right away! Now my infrastructure as code is easier to use, the scripts are a little bit more seamless, and everything is wrapping into a good development workflow a bit better.

For JavaScript, Go, Python, Terraform, and more infrastructure, web dev, and coding in general I stream regularly on Twitch at, post the VOD’s to YouTube along with entirely new tech and metal content at

Pragmatic Database Schema Naming Conventions, Practices, and Patterns

In this post I’ve put together some of the naming conventions, rules, and ideas that I tend to follow when creating database schemas to work with. This also applies to schema-less databases, distributed systems databases, graph, time series, or whatever else I am working with. It’s always good to have some good conventions to work with, and the descriptions and ideas in this post are a solid starting point.

What We’re Working With, Some of The Database Rules

Let’s start with a SQL Server rule. Table names must be less than 128 characters. To force SQL Server to use non-standard table names one can use brackets. Then in scripts these names have to be single quoted.

There are many other rules about naming things in SQL Server. But let’s talk about some other database specific rules for other databases.

Postgres names fold to lowercase versus uppercase, which is different then many other databases. Throw in some double quotes however and you can use names like MyTable, MYTABLE, and mytable. These would all be the same without double qutoes, add the double quotes around those names and “MYTABLE” becomes different than “MyTable” and different than “mytable”.

SQL identifiers in Postgres and key words must begin with letters (a-z), which include diacritical marks and non-Latin letters. After the first letter and identifier can have letters, underscores, digits, or dollar signs. If an identifier is double quoted, you can also yse keywords, albeit I would very strongly reccommend against this practice.

As these examples provide, there are a number of ways that the rules are just different enough from one database to another that it is often very helpful to use a naming convention that would work across databases. I’m often working with a variety of databases so this post will cover naming convention ideas and respective patterns and practices around them that would work with every conceivable database I know to exist!

Table, Column, Tuple, or Related Naming Conventions

  • Table, column, and related object names should contain only letters, numbers as characters in the body of the name and not as the preface characters, underscores and absolutely no spaces or special characters. In summary, use a case scheme like Camel or Pascal Case but do not use Snake or Kebab Case.
  • Use meaningful names from the business or organizational domain being modeled. Such as “BankingUsers”, “Transactions”, “railroads”, or “railroad_Systems”.
  • Use singular word names if at all possible, only moving to compound word naming if absolutely necessary. Ideally names would be single words like “User”, “Transactions”, “railroad”, or “system” and exclude compound names like “railroadSystem” until it is needed to prevent confusion or naming collisions.
  • Columns that are primary or foreign keys should be prefaced with PK_ and FK_ respectively, and in my moderately humble opinion, stick to just PK or FK using Camel or Pascal Case. For other metadata, indexes, and related names use a respective preface or postfix conventions.
  • It’s also a good idea to choose plural or singular for table names. However, be sure to choose one or the other so that frameworks, Object Relationship/Relational Mappers/Mapping (ORM), and other tools can effectively name things when used. For example, when table names are singular, many ORM frameworks when generating code would take a singular table name like Customer and make it Customers and have objects of Customer.

Schema/Domain Naming Conventions

In many databases there are additional organizational and related structures that help us to setup tables, functions, stored procedures, compiled SQL/queries, and other objects in groupings. Naming these objects accordingly is easiest by following the same convention as the table naming convention.

For example, if the table naming convention is following Camel Case then continue that;

Table Names for Returns in an E-commerce Domain:

  • Purchase
  • Return
  • Shipped

Table Names for Pricing in an E-commerce Domain:

  • Price
  • Cost

Table Names for Core Tables, for multiple schemas, within the E-commerce Domain:

  • Item

This could be split out to three schemas;

  • Core
  • Prices
  • Returns

The names would then look like this:


An Example

Here’s an example I put together with some naming conventions I’ve found useful, reduces confusion, and manages to tell a reasonable amount of information about the domain space and schema of the database without conflicts.

The Database Schema

Throughout this schema I’ve used Camel Casing, with most single word column and single word table names. Keeping it simple, such as Id and Stamp are some of the recurring columsn that are useful for retrieval, relationships, and determining origins of data over time. In production settings there are default columns that are often needed and one can rest assured, a time stamp is most likely one of those that is needed everywhere for audits!

For my foriegn key columns, one can determine the relationship by the name of the column itself. For example, in the Connection table the are two foreign keys, one to the Action table and one to the Source table, to the respective Id columns in each of those tables. The one exception is NoteJot, which I named because Note tends to conflict in certain systems. In that table I’ve added a relationship, for recursive data, back to itself with the use of the NoteId foreign key back to the table’s primary key Id.

The diagram above, without any further details can be used to create the schema, with SQL code that would look like the following.

  "Id" uuid PRIMARY KEY,
  "Stamp" timestamp,
  "Name" text,
  "Uri" text,
  "Details" text

CREATE TABLE "SourceNotes" (
  "SourceId" uuid,
  "NotesId" uuid,
  "Details" text,
  "Stamp" timestamp

  "Id" uuid PRIMARY KEY,
  "Stamp" timestamp,
  "NoteId" uuid,
  "Details" text

  "Id" uuid PRIMARY KEY,
  "Stamp" timestamp,
  "Action" json

CREATE TABLE "Connection" (
  "Id" uuid PRIMARY KEY,
  "Stamp" timestamp,
  "ActionId" uuid,
  "SourceId" uuid

CREATE TABLE "Formatter" (
  "Id" uuid PRIMARY KEY,
  "Stamp" timestamp,
  "ConnectionId" uuid,
  "FormatterMap" json

  "Id" uuid PRIMARY KEY,
  "Stamp" timestamp,
  "ConnectionId" uuid,
  "SchemaMap" json

ALTER TABLE "SourceNotes" ADD FOREIGN KEY ("SourceId") REFERENCES "Source" ("Id");

ALTER TABLE "SourceNotes" ADD FOREIGN KEY ("NotesId") REFERENCES "NoteJot" ("Id");


ALTER TABLE "Connection" ADD FOREIGN KEY ("ActionId") REFERENCES "Action" ("Id");

ALTER TABLE "Connection" ADD FOREIGN KEY ("SourceId") REFERENCES "Source" ("Id");

ALTER TABLE "Formatter" ADD FOREIGN KEY ("ConnectionId") REFERENCES "Connection" ("Id");

ALTER TABLE "Schema" ADD FOREIGN KEY ("ConnectionId") REFERENCES "Connection" ("Id");

We have the tables and keys, all following the Camel Case standard. Much of this however could be – if you preferred – to Pascal Case however switching them to Snake or Kebab Case would cause a number of issues depending on the database.

Do NOT Use These

Unless you want to spend tons of time with errors, debugging, and related issues skip these practices.

  • Generally throughout databases it is best to skip Snake or Kebab Case. Various situations they’re fine, but overall they’re likely to run into conflicts, naming limitations, or other concerns. It’s best to just skip them and remove the concern.
  • When you’re using data that has variance in how it is represented, do not use multitudes of formats. For dates, location, geographic, or related data it is best to stick to a particular format that is repeated throughout the database. Using mixed representations, for example with dates a MMDDYYYY format and then a DD-MM-YYYY format, methods, functions, or other elements that consume or process this data will need to account for this. Creating more time consuming and error prone code.
  • Once you pick a naming scheme for any particular database object type, stick to the naming scheme. For example, if you go with Camel Casing for your tables, use Camel Casing for all of the tables and don’t switch to Pascal for some of them. Specifically, however with this guidance, is if you switch object types, for example you name the tables Pascal Cased but switch to Camel Case for indexes, that’s perfect. Then if ever reviewing a list of objects irrespective of kinds of objects, one can differentiate merely by the conventions used.

Summary & Caveat

Working up a set of patterns, practices, rules, and generally conventions to work with on the database side of things is immensely useful. It helps the Database Administrators, Data Scientists, Software Developers, others that need to utilize the database, and to communicate with each other in reference to the database and data.

That’s it for the database schema topic for now. However, if you’re interested in joining me for more database and data oriented things, language stack setup, software development, patterns, practices, and more in addition to writing some JavaScript, Go, Python, Terraform, and infrastructure, web dev, and all sorts of coding I stream regularly on Twitch at, post the VOD’s to YouTube along with entirely new tech and metal content at Feel free to check out a coding session, ask questions, interject, or just come and enjoy the tunes!

Name Casing Conventions, The Quick Comparison

There are a number of name casing practices, which I’ll cover in quick fashion here, for variables and other objects when programming.

The Quickie Synopsis

  • camelCaseLikeThis
  • PascalCaseLikeThis
  • snake_case_like_this
  • kebab-case-like-this
  • MixAnd-match_like-this

Camel Case

With Camel Case the first letter of the first word is lower case, then every subsequent first letter of each word is upper cased. For example, thisIsCamelCasedsomething if a singular word, or somethingElse.

My 2 ¢ – I’m a big fan of this case when I’m name private variables or related objects. I’m also a fan of using Camel Casing for certain types of functions, especially in JavaScript such as this.doesStuff() or somethingAnother.doesOtherStuff().

Pascal Case

In usage of Pascal Case, the first letter of each word within the name is upper cased. Examples include ThisOjectThatThing, or WhateverElse().

My 2 ¢ – This is something I like to use for class declaracters (i.e. public class ThisClassThing) and then for functions or methods on that class, or respectively similarly for functions on functions in JavaScript, or the like. Basically, anything that will be used similar to MyThing.DoesThisThing().

Snake Case

Using Snake Case has the empty spaces replaced with underscores. So a file name like this is my would become

My 2 ¢ – Snake case is great when I need to have variables that would otherwise have spaces, but also wouldn’t be displayed regularly with anything that might obfuscate the underscore, such as an HTML.

Kebab Case

Kebabs are tasty, the case however is similar to Snake Case, except instead of underscores dashes are used. Each space in the name is replaced with a - character. Such as my-table-name-is-this or this-is-a-variable.

My 2 ¢ – Kebab case is excellent for filenames, URIs, or something of that sort where spacing between the words of a file or path are important to read, but an underscore would be obfuscated by the font rendering such as with a URI.

Hasura CLI Installation & Notes

This post just elaborates on the existing documentation here with a few extra notes and details about installation. This can be helpful when determining how to install, deploy, or use the Hasura CLI for development, continuous integration, or continuous deployment purposes.


There are three primary operating system binary installations: Windows, MacOS, and Linux.


In the shell run the following curl command to download and install the binary.

curl -L | bash

This command installs the command to /usr/local/bin, but if you’d like to install it to another location you can add the follow variable INSTALL_PATH and set it to the path that you want.

curl -L | INSTALL_PATH=$HOME/bin bash

What this script does, in short, follows these steps. The latest version is determined, then downloaded with curl. Once that is done, it then assigns permissions to the binary for execution. It also does some checks to determine OS version, type, distro, if the CLI exists or not, and other validations. To download the binary, and source if you’d want for a particular version of the binary, check out the manual steps listed later in this post.


For MacOS the same steps are followed as Linux, as the installation script steps through the same procedures.

curl -L | bash

As with the previous Linux installation, the INSTALL_PATH variable can also be set if you’d want the installation of the binary to another path.


Windows is a different installation, as one might imagine. The executable (cli-hasura-windows-amd64.exe) is available on the releases page. This leaves it up to you to determine how exactly you want this executable to be called. It’s ideal, in my opinion, to download this and then put it into a directory where you’ll map the path. You’ll also want to rename the executable itself from cli-hasura-windows-amd64.exe to hasura.exe if for any reason because it’s easier to type and then it’ll match the general examples provided in the docs.

To setup a path on Windows to point to the directory where you have the executable, you’ll want to open up ht environment variables dialog. That would be following Start > System > System Settings > Environment Variables. Scroll down until the PATH is viewable. Click the edit button to edit that path. Set it, and be sure to set it up like c:\pathWhatevsAlreadyHere;c:\newPath\directory\where\hasura\executable\is\. Save that, launch a new console and that new console should have the executable available now.

Manual Download & Installation

You can also navigate directly to the releases page and get the CLI at All of the binaries are compiled and ready for download along with source code zip file of the particular builds for those binaries.

Installation via npm

The CLI is avialable via an npm package also. It is independently maintained (the package that wraps the executable) by members in the community. If you want to provide a set Hasura CLI version to a project, using npm is a great way to do so.

For example, if you want to install the Hasura CLI, version in your project as a development dependency, use the following command to get version 1.3.0 for example.

npm install --save-dev hasura-cli@1.3.0

For version 1.3.1 it would be npm install --save-dev hasura-cli@1.3.1 for example.

The dev dependencies in the package.json file of your project would then look like the following.

"devDependencies": {
  "hasura-cli": "^1.3.0"

Another way you can install the CLI with npm is to just install it globally, with the same format but swap the --save-dev with --global. The following would install the latest command. You can add the @version to the end and get a specific version installed globally too, just like as shown with the dev install previously.

npm install --global hasura-cli


Using the npm option is great, if you’re installing, using, writing, or otherwise working with JavaScript, have Node.js installed on the dev and other machines, and need to have the CLI available on those particular machine instances. If not, I’d suggest installing via one of the binary options, especially if you’re creating something like a slimmed down Alpine Linux container to automate some Hasura CLI executions during a build process or something. There are a lot of variance to how you’d want to install and use the CLI, beyond just installing it to run the commands manually.

If you’re curious about any particular installation scenarios, ask me @Adron and I’ll answer there and I’ll elaborate here on this post!

Happy Hasura CLI Hacking! 🤘