SchemaSmith Documentation

Schema Packages

The on-disk representation of a database schema definition. Every tool in the suite reads, writes, or modifies schema packages.

By the SchemaSmith Team · Last reviewed

Schema Packages

A schema package is your database's source of truth — the complete, version-controlled definition of what your databases should look like.

Overview

A schema package is the on-disk artifact that every SchemaSmith tool produces or consumes. It is a folder — or a .zip archive of that folder — holding the product and template configuration, the table definitions, the SQL scripts, and the JSON Schemas that validate every file in the package. One package, one deployable unit, one source of truth.

The package's contents are described elsewhere in the documentation: see Products and templates for the JSON configuration files at the package's core, Defining tables for the table JSON format, and Data delivery alongside Conditional application for the declarative data and deployment controls table files can carry. This page focuses on the package as a container: where files live, how the folder tree is laid out, how ZIP distribution works, and how filesystem-illegal object names get encoded onto disk.

Complete Folder Structure

A schema package is a predictable directory tree. Every tool in the SchemaSmith toolset discovers what it needs by convention — Product.json at the root, Templates/ one level down, platform-specific script folders inside each template — so you never have to configure paths or point a tool at individual files. Marker files and generated artifacts sit alongside the files you author, and the whole layout maps cleanly onto source control.

MyProduct/
  Product.json                      Product configuration (required)
  .json-schemas/                    JSON Schema files for IDE validation (generated)
    products.<platform>.schema      <platform> = sqlserver, postgresql, or mysql
    templates.<platform>.schema
    tables.<platform>.schema
    indexedviews.sqlserver.schema             SQL Server packages
    materializedviews.postgresql.schema       PostgreSQL packages
  .community                        Marker file (generated by SchemaTongs)
  Before Product/                   SQL scripts run before all templates
  After Product/                    SQL scripts run after all templates
  Templates/
    TemplateName/
      Template.json                 Template configuration (required)
      Tables/                       Table definition JSON files (all platforms)
        public.customer.json
        sales.order.json
      Indexed Views/                Indexed view definitions (SQL Server only)
        dbo.vw_OrderSummary.json
      Materialized Views/           Materialized view definitions (PostgreSQL only)
        public.mv_active_orders.json
      data/                         DataDelivery content files (.tabledata)
        public.customer.tabledata
      <platform default folders>    See Default Folders on Products and Templates
      <custom folders>              Anything you declared in ScriptFolders

Table JSON files are named schema.tablename.json (e.g., dbo.Customer.json, public.order_lines.json). MySQL carries no per-table schema, so MySQL packages drop the segment entirely and name the file tablename.json. If a table or schema name contains filesystem-illegal characters, the encoded form is used in the filename — see Filesystem-Illegal Character Encoding.

SQL script files can be organized into subdirectories within any script folder. All .sql files are discovered recursively and sorted alphabetically by full path.

File naming

How you name table JSON files depends on your platform, the template kind — regular template or schema template — and, in a regular template, whether the table carries conditional variants.

Regular templates use schema-prefixed filenames. The prefix mirrors the table's Schema property, so a file listing tells you at a glance which schema each table belongs to: dbo.Customers.json, Sales.Orders.json, public.order_lines.json. A table that omits Schema falls back to the platform default — dbo on SQL Server, public on PostgreSQL. MySQL has no per-table schema, so MySQL packages use unqualified filenames throughout, whatever the template kind.

Schema templates use unqualified filenames. The schema is the iteration variable — SchemaQuench resolves {{SchemaName}} at runtime for every iteration, so Customers.json deploys into acme.Customers for the acme tenant, globex.Customers for the globex tenant, and so on. Filenames with a schema prefix (e.g., dbo.Customers.json) inside a schema template's Tables/ folder are rejected by the engine at load time.

Cross-schema tables. A schema template cannot own a table in a specific named schema, so there is no way to express that with a filename: dbo.SharedConfig.json inside a TenantWorkspace/Tables/ folder is rejected at load time like any other schema-prefixed name. Put cross-schema tables in the accompanying regular template that runs first in TemplateOrder.

The accompanying Shared regular template (if present) follows the standard prefix convention: dbo.Tenants.json, public.countries.json. Its filenames are unchanged by the presence of a schema template in the same product.

Conditional variants. Within a regular template, a table carrying conditional variants takes an optional VariantName segment after the table name — dbo.Customers.Premium.json sitting beside dbo.Customers.json — so a table's variants sort together in source control and in a file listing.

SchemaTongs writes each table file under the canonical name for your platform and template kind, but that name is a convention rather than a contract. A table's identity lives in its file content, so a file you renamed by hand still deploys, and re-extraction refreshes it in place instead of duplicating it. Running SchemaQuench with --Validate reports any drift from the canonical form as an SS-FILE-NAME-003 warning naming the expected filename.

For the canonical form on your platform, with its exact schema-segment rule, see the SchemaTongs reference: SQL Server, PostgreSQL, or MySQL.

For a worked layout showing these conventions side by side, see Multi-Tenant Deployments.

.json-schemas Folder

Your IDE can help you write correct JSON if you point it at the right schemas. The .json-schemas/ directory at the package root contains JSON Schema definition files generated automatically by SchemaTongs on the fly from the live C# domain types — no embedded files, no shipped artifacts, just a snapshot of the engine's exact current shape.

Each file carries a platform infix matching the package's platform — <platform> is sqlserver, postgresql, or mysql:

File Validates
products.<platform>.schema Product.json
templates.<platform>.schema Template.json
tables.<platform>.schema Table JSON files (Tables/*.json)
indexedviews.sqlserver.schema Indexed view JSON files (SQL Server packages)
materializedviews.postgresql.schema Materialized view JSON files (PostgreSQL packages)

Because the schemas are regenerated every time SchemaTongs writes a package, they always match the current engine. If you've hand-edited any of them to add a custom validation fragment under Extensions, that fragment is preserved through regeneration — see Custom Properties: JSON Schema Validation.

ZIP Package Support

SchemaQuench can consume schema packages as ZIP archives. When the SchemaPackagePath configuration value points to a .zip file, SchemaQuench reads the package directly from the archive without extracting it to disk first.

Requirements:

  • The ZIP must contain the standard schema package folder structure.
  • The Product.json file must be at the root of the archive (not nested inside an extra directory).
  • All relative paths within the package must match the standard layout described in Complete Folder Structure.

This is useful for deployment pipelines where the schema package is built as a single artifact.

Filesystem-Illegal Character Encoding

Object names can contain characters that are illegal in file paths on Windows, macOS, or Linux. SchemaTongs uses a percent-encoding scheme to safely map these names to filenames.

Character Encoded As
\%5C
/%2F
:%3A
*%2A
?%3F
"%22
<%3C
>%3E
|%7C
%%25

Additional rules:

  • Leading spaces and dots are encoded (%20 for space, %2E for dot) because many filesystems strip or reject them at the start of filenames.
  • Trailing spaces and dots are similarly encoded.
  • Reserved Windows device names (CON, PRN, AUX, NUL, COM1–COM9, LPT1–LPT9) have their first character percent-encoded.

SchemaQuench decodes these filenames transparently when reading definitions. You generally don't need to worry about encoding unless you're creating JSON files by hand for tables with unusual names.

Hands-on lab

Build a schema package folder structure from scratch, add your table definitions, and run them through SchemaQuench.

Build a package