Skip to main content

Seed Data as Code: Lookup Tables and Reference Data

A large part of an application's behavior lives in rows your code reads at runtime: country codes, currencies, status types, plan tiers, feature flags. These rows are part of your application contract, but they almost always live outside it: bootstrapped by ad-hoc INSERT scripts and drifting between environments.

Atlas applies the same shift-left workflow to data that it applies to schema. Declare the desired rows in HCL data blocks or plain SQL INSERT statements alongside the tables that hold them, and Atlas plans the exact INSERT / UPDATE / DELETE needed to bring any database to that state in the same pull request as your DDL.

Choose a Sync Mode

Different tables have different lifecycles. A countries table is mostly static. A feature_flags table is edited often. A plan_tiers table must match the desired state exactly.

For each table, Atlas compares the rows you declared to the rows in the live database (matched by primary key), and generates the DML needed to bring them in line. The sync mode is a per-environment policy that controls which kinds of DML Atlas is allowed to emit: just INSERTs for new rows, INSERTs plus UPDATEs for changed rows, or full INSERT / UPDATE / DELETE reconciliation including removal of rows that are no longer declared.

Get Started by Database

The guides below use PostgreSQL and MySQL as concrete examples, but the data block, sync modes, and env configuration work across every database Atlas supports, including Spanner, Snowflake, and the rest. Each example walks through configuring atlas.hcl, declaring rows in HCL or SQL alongside the schema, and applying changes through INSERT, UPSERT, and SYNC modes.

Defining Data

Data can be authored as HCL data blocks or plain SQL INSERT statements alongside the tables they populate. The references below cover both syntaxes, the env-level data block that enables synchronization, and the rules for skipping columns from the diff.

Dynamic Data Sources

Both HCL and SQL support dynamic data definitions, so your seed data is never limited to static, hand-written rows:

  • HCL: define computed resources, inject values through input variables, and read external datasets (CSV, JSON, HTTP responses, or the output of any external program) through data sources.
  • SQL: the same data sources are available, with template directories providing the templating layer that turns a compact definition into a full dataset.