Skip to content

Course 4 · Recipe 4 — Assets that travel with the schema

There’s always something that belongs with the schema but isn’t schema. A default logo. A signing certificate. A static set of reference rows every install needs. So it ends up loaded by hand — someone runs a script with a giant hex blob pasted in, or copies a seed file between environments, and gets the encoding subtly wrong on one engine. The asset should ride inside the package and land itself. It can.

A token’s value can start with a tag that reads a file at deploy time. Two of them carry content:

"ScriptTokens": {
"DefaultLogo": "<*BinaryFile*>resources/logo.png",
"SeedCategories": "<*File*>resources/seed-categories.sql"
}
  • <*BinaryFile*> reads the file and emits it as the platform-appropriate binary literal0x… for SQL Server and MySQL, E'\x…'::bytea for PostgreSQL.
  • <*File*> reads a text file and embeds its contents verbatim wherever the token is referenced.

Both resolve relative to the package, so the files travel in source control alongside your tables. A deploy script then just references them:

-- Seed Brand Assets [ALWAYS].sql
INSERT INTO BrandAssets (AssetName, Image) VALUES ('Default', {{DefaultLogo}});
{{SeedCategories}}

The recipe: one logo, three engines, byte-for-byte

Section titled “The recipe: one logo, three engines, byte-for-byte”

resources/logo.png is a real 69-byte PNG, identical in every engine folder. Deploy, then read the stored image back:

SQL Server → 69 bytes, 89504e47…ae426082
PostgreSQL → 69 bytes, 89504e47…ae426082
MySQL → 69 bytes, 89504e47…ae426082

Same length, same hex — the PNG signature and every byte of the file you shipped, on all three engines. You authored one <*BinaryFile*> token; SchemaSmith emitted a VARBINARY literal here, a BYTEA literal there, a BLOB literal there, and the bytes round-tripped identically. The <*File*> reference data lands the same way — Books, Electronics, Garden seeded from one file embedded at deploy.

The aha: author once, land native everywhere

Section titled “The aha: author once, land native everywhere”

This is the multi-engine promise in miniature. The hard part of shipping binary across engines is that each one wants its own literal form, and getting it wrong corrupts the bytes silently. <*BinaryFile*> makes that the resolver’s job, not yours — you point at a .png and each target gets exactly the literal it accepts. Want the full list of file tags and how they resolve? The Script Tokens reference covers <*File*>, <*BinaryFile*>, and <*QueryFile*>.

Check yourself: How do you seed the same binary asset into a SQL Server, PostgreSQL, and MySQL database from one package without per-engine editing?

Point a token at the file with <*BinaryFile*> — SchemaSmith emits the platform-correct binary literal (0x… for SQL Server and MySQL, E'\x…'::bytea for PostgreSQL) automatically. Your script just references {{TokenName}}; the resolver picks the right form for each target, so the same .png lands byte-for-byte on all three.


Think of the maker’s mark again — but this time it’s not the dimensions, it’s a stamp you press into every piece: a logo, a seal, the reference set that makes the part usable. You cut the stamp once and it travels with the metal into whatever forge takes it, pressing the same mark whether the fire’s SQL Server, PostgreSQL, or MySQL. The shape of the literal changes to fit the fire; the mark itself arrives whole.

Got an asset you’re loading by hand right now — a logo, a cert, a seed dataset you paste in per environment? Email me at forgebarrett@schemasmith.com — I read every one.

Next up: Course 4 · Recipe 5 — Scripts that write scripts, where a deploy-time script reads your declared model and generates per-table DDL from it.

Until then, may everything you forge carry its mark wherever it travels, and arrive whole in every fire.

— Forge