Tutorials › Database

Metals Simple Deploy · Database

The Metals Database, Structure and Local Setup

Every table this application uses is defined in one file — sql/metals-db.sql — and a local copy of the database can be stood up with one file at the project root, docker-compose.yml. This page covers what's actually inside that schema, including the new users, roles, and user_roles tables added for authentication, and how to run (and, if needed, reset) the database on your own machine.

Codey the Sr Developer, standing with a pointer, ready to walk through the guide
Engine → PostgreSQL 16 Schema & seed data → sql/metals-db.sql Local runtime → docker-compose.yml Tables → 7 Dev seed accounts → admin & customer

One file, one source of truth start here

sql/metals-db.sql does two jobs in one script: it drops and recreates every table this project needs (in dependency order, so foreign keys don't fail), and then it inserts starting data — including the roles, the two development login accounts, and the metals/alloys/coins catalog data the API serves.

Codey typing on a laptop
one script, every table
Where this file is usedtwo places

Locally, docker-compose.yml mounts this file straight into a fresh PostgreSQL container so it runs automatically the first time the container starts — covered on the next page. In Azure, the same file is loaded by az_create_resources (manual path) or terraform/scripts/initialize_database.py (Terraform path) after the empty database server is created.

The tables, table by table structure

Seven tables in total, split into two groups: the metals catalog data the API was originally built around, and the authentication tables added on top of it.

TableWhat it's for, in plain terms
elementsOne row per chemical element (atomic number as the primary key) — melting/boiling points, color, density, category, and whether it's toxic or magnetic.
alloysNamed mixtures, like “Sterling Silver” or “18K Yellow Gold.”
alloy_elementsA join table: which elements make up which alloy, and what percentage of the alloy each one is.
coinsReal-world coins, each made from one alloy, with weight and face-value details.
usersLogin accounts — a username and a password hash (never the real password). (dig deeper)
rolesThe two permission levels this API knows about: Admin and Customer. (dig deeper)
user_rolesA join table connecting users to the role(s) they hold. (dig deeper)

Bold rows are the three tables added for authentication. Everything else was already part of the metals catalog.

What gets loaded automatically seed data

After creating the tables, the same script inserts starting rows: the Admin and Customer roles, two ready-to-use login accounts, and a large catalog of real elements, alloys, and coins. Every insert uses ON CONFLICT ... DO NOTHING, so re-running the script against a database that already has this data is harmless.

Codey holding up a sticky note
safe to run more than once

The two seed accounts and their password are covered in detail on the Docker Compose page — you'll need them to log in once the Metals API requires authentication.

Pick a page to learn go deeper

Codey giving a thumbs up

Pick a page above, or head to the Metals API tutorial to see who actually calls this database.