What's New

Track SchemaSmith updates across SQL Server, PostgreSQL, MySQL, and MariaDB — from SchemaTongs extraction to SchemaQuench deployments to DataTongs data sync.

SchemaSmith release notes and version history

Leaving EnableCDC out of a table now leaves its change data capture alone, DataTongs reports failed tables through its exit code, and a failed run no longer records its version as deployed.

Check these changes before you upgrade
  • Breaking Leaving out EnableCDC no longer turns CDC off — On SQL Server, leaving it out of a table used to mean false, so a deploy turned off change data capture on any table where it had been enabled outside the package, dropping the capture instances and their change history. Leaving it out now changes nothing; true turns CDC on and false turns it off. A package that relied on leaving it out to turn CDC off must now say "EnableCDC": false.
  • Enhanced DataTongs exit codes report failed tables — DataTongs still moves past a table it cannot extract, but it no longer exits 0 however many tables failed. It exits 0 when every configured table was extracted, 1 when the run finished with something not fully produced (such as a table skipped because it is missing from the source or has no key columns, or a column whose type cannot be delivered), and 2 when at least one table failed. Each skipped or failed table is named, with the reason, in the progress log and in DataTongs - Errors.log. Check how your pipeline treats exit code 1.
  • Enhanced A missing --ConfigFile stops the run — A settings file named with the switch that does not exist now stops every tool with exit code 2 before anything connects, naming the path it tried. It used to be ignored, and the tool ran without those settings. The default settings file is unchanged: when it is absent, the tool still runs on its other settings.
  • Enhanced TemplateOrder entries are folder names — Each entry is the name of a folder directly under Templates/, matched without regard to case on every OS, and never a path. The operating system used to decide what an entry meant, so one package could load on Windows and fail on Linux, or the reverse. An entry that is not a plain folder name, such as ./Main, or that matches no folder, is now refused by both the deploy and --Validate.
Choose the index CDC uses, and keep the indexes you rely on
  • New CdcIndexName sets the index CDC identifies rows by — Name a unique index for a table's capture instance to use in place of the primary key (SQL Server's @index_name), so a table with no primary key can have net changes. It must be a declared unique index over NOT NULL columns; otherwise the deploy fails before CDC is enabled, naming the table and the problem, and --Validate reports SS-CDC-002. Changing it rotates to a new capture instance, and SchemaTongs extracts it when the newest capture instance uses an index other than the primary key. See Identifying rows.
  • Fix The index a capture instance uses is protected — A deploy that would drop, rename or redefine an index a capture instance identifies rows by, the primary key included, is now refused before any index is touched, naming the index and the capture instance. SQL Server used to refuse the drop only partway through the index work, and allowed a rename that left the instance naming an index that no longer existed. To move off such an index, set CdcIndexName to another unique index and deploy, drain and drop the old capture instance, then make the change.
  • Fix Spatial, JSON and selective XML indexes are left alone — A package cannot declare these yet, so SchemaTongs now leaves them out of the table file and names each one in a warning, and SchemaQuench neither compares nor drops them, even with DropUnknownIndexes on. Create and maintain them with a script. SchemaTongs used to extract a spatial or JSON index as a plain index that the next deploy refused, and a deploy that drops unknown indexes dropped them.
Deploys that do what their output reports
  • Fix Every database gets every script — A template whose DatabaseIdentificationScript returns several databases now runs every script in every one of them. A script applied in one database used to be skipped in the databases whose pass started afterwards, and those databases still reported success.
  • Fix A failed run no longer stamps its version — After a failure, the product's After Product scripts and its VersionStampScript are now skipped, so the next run is not told this version is deployed. With ContinueOnDatabaseFailure on (the default), a run in which a template failed used to run them anyway. The exit code is still 2, and a later --ResumeQuench that finishes the failed work runs them.
  • Fix WhatIf previews foreign keys — A WhatIf run used to skip the foreign-key step entirely, so a package adding a foreign key showed none in the WhatIf summary while the real run created it. The foreign keys a deploy would create now appear in the preview.
Catch problems before a deploy starts
  • New Duplicate foreign-key names are caught — --Validate now reports a foreign-key name used on two tables in one template as SS-FK-006. MySQL names foreign keys per database and SQL Server per schema, so the second one fails the deploy, and the finding is an Error. MariaDB names them per table from 12.1, so there it is a Warning, and there is no finding at all when the product's MinimumVersion is 12.1 or later.
  • Enhanced Unreadable LogHygiene settings are reported — A single value where a list belongs ("ScrubTokens": "DeployKey" instead of [ "DeployKey" ]), a key that is not a LogHygiene setting, or a LogTokens value other than true or false is now a warning naming the key. These used to be ignored silently, so a value you meant to mask could be logged in clear. Fix each warned key before relying on masking.

SQL Server change data capture, Change Tracking and FILESTREAM now apply when SchemaQuench deploys them, a feature the server's version cannot support is now reported, and change data capture gains filegroup placement and net changes.

SQL Server table features now apply on deploy
  • Fix Change data capture deploys again — In v2.7.0 a SchemaQuench deploy did not apply EnableCDC: it enabled, rotated and disabled nothing, and reported success. SchemaQuench now runs that step itself, after every column exists, so a capture instance includes the table's computed columns.
  • Fix Change Tracking and FILESTREAM now apply — Both shipped in v2.6.0, but a SchemaQuench deploy never applied them: EnableChangeTracking, TrackColumnsUpdated and a declared FileStream column deployed as nothing, with no error. Both now apply, after indexes and constraints. Leaving EnableChangeTracking out leaves a table's tracking as it is, so tracking a DBA enabled by hand is kept; only "EnableChangeTracking": false turns it off. A FileStream column now also enforces SQL Server's requirement for a ROWGUIDCOL column covered by a single-column primary key or unique constraint, and names the table when it is missing.
  • Fix UnsupportedFeaturePolicy does its job on SQL Server — Since v2.4.0, a deploy below a feature's minimum SQL Server version skipped the unsupported DDL but recorded no downgrade in the deployment summary, logged nothing, and ignored fail. The downgrade is now reported, and under fail the deploy stops before anything changes.
Change data capture you can tune and trust
  • New CdcFilegroup places change tables — Set it on a table, or on Template.json as the default for every EnableCDC table, to put change tables on a filegroup of your choosing instead of the database default. Changing it never moves a change table: the deploy rotates to a new capture instance on the declared filegroup and keeps the old instance's history for you to drain and drop. Introduced in v2.7.0, it first takes effect in a v2.7.1 deploy. See Where change tables go.
  • New CdcSupportsNetChanges declares net-change support — On a table, or on Template.json as the default, it sets whether a capture instance supports net changes (SQL Server's @supports_net_changes). With it on, SQL Server generates the net-changes query function; true requires a primary key and is refused by name on a table without one. Unset keeps what earlier versions produced. See Net changes.
  • Fix Capture instances catch up on their own — A table can have only two capture instances, and at that limit a new column used to be added before the deploy refused, leaving it uncaptured even after the documented recovery. The limit is now checked before any column is added, and SchemaQuench rotates whenever a table's newest capture instance does not capture exactly its current columns — including an instance created before the table's computed columns existed — keeping the old instance and its history for you to drain and drop. If both slots are already in use, the deploy warns instead, naming the table.

DataTongs stops deleting rows unless you ask it to, settings that never did anything on an engine now say so, and deploys stop rebuilding what didn't change. SQL Server change data capture users should install v2.7.1 instead: in this release, a SchemaQuench deploy did not apply EnableCDC.

Review these settings before you upgrade
  • Breaking ShouldCast:MergeDelete is now opt-in — A DataTongs settings file that didn't mention the key used to generate MERGE scripts with the delete branch, removing target rows the extracted source did not contain, so deleting the key was not the same as setting it false. It now defaults to false; set "MergeDelete": true to keep the delete branch. A per-table MergeType was always authoritative and is unaffected.
  • Breaking Column-level checks on MySQL and MariaDB are retired — A package that still declares CheckExpression on a MySQL or MariaDB column now fails to load, naming the property and the file, before anything changes. Move each one to the table's CheckConstraints and keep the name the alias generated, CK_<table>_<column>, so the deployed constraint is matched rather than dropped and recreated. PostgreSQL and SQL Server are unaffected.
  • Breaking Engine-specific settings are rejected where they did nothing — MergeDisableRules and MergeUpdateDescendents (PostgreSQL only), DropExcludeConstraintsRemovedFromProduct (PostgreSQL only) and DropStatisticsRemovedFromProduct (SQL Server and PostgreSQL only) used to be accepted and silently ignored on other engines. Authoring one there now fails --Validate with SS-JSON-001. Delete the property — it never had an effect on that engine.
Deploy only what actually changed
  • Fix Expressions no longer churn on every deploy — Every engine rewrites an expression when it stores it, so comparing your package against the catalog made an unchanged expression look modified, and it could be re-applied on every deploy. A new SchemaSmith-owned table, SchemaSmith.ExpressionMap (SchemaSmith_ExpressionMap on MySQL and MariaDB), records the text you declared, the text the engine reported back, and the engine version in force. It is safe to empty; the only cost is one more comparison on the next deploy.
  • Fix Re-extraction leaves unchanged table files alone — Re-extracting an unchanged database with SchemaTongs used to rewrite every table file. It no longer does, so a refresh committed to source control shows only real changes.
Packages deploy exactly as written
  • Fix MySQL and MariaDB tables get their declared character set and collation — A table's CharacterSet and Collation were never emitted, so the table was created at the server's default. They are now applied.
  • Fix PostgreSQL renames work with a quoted OldName — A quoted OldName made a rename silently do nothing, and left the old table to be dropped later, with its data.
  • Fix Names containing a delimiter character round-trip — A ] in a SQL Server name (written ]] inside the brackets) and a backtick in a MySQL or MariaDB name now extract, create and rename correctly.
Validate and edit with less friction
  • New Packages carry a $schema reference — Each package JSON names its own schema in the package's .json-schemas/ folder, so an editor validates and autocompletes it with no setup. Extraction stamps it, and SchemaTongs --WriteSchemasOnly adds it to an existing package. A package carrying the key will not load on SchemaSmith v2.6.0 or earlier, which matters if more than one version deploys the same package during an upgrade.
  • New --Validate catches PostgreSQL objects declared twice — An enum type, sequence or domain type declared both as JSON and as a .sql script is now reported (SS-ENUM-001, SS-SEQ-001, SS-DOM-001). These are Error-severity findings on packages that used to pass, so a CI step gated on --Validate fails until you delete whichever form you did not mean to keep.
  • Fix SchemaShears patches can be gated in CI — --Validate failed any package with a foreign key to a table it does not declare, so every patch whose table carried a foreign key failed although it deployed correctly. SS-FK-002 is now a warning, because the deploy creates such a key whenever the table already exists on the target.

Ledger, graph, and partitioned tables are declared now instead of hand-scripted, PostgreSQL sequences and enum types converge on deploy rather than sitting in guarded scripts that never run twice, and captured change history stops disappearing when you alter a column.

Declare SQL Server's specialized table types
  • New Memory-optimized tables — Set MemoryOptimized: true and optionally Durability; "SCHEMA_AND_DATA" is the default and keeps both schema and rows across a restart, "SCHEMA_ONLY" keeps the schema and discards every row. Indexes are declared in the ordinary Indexes array and emitted inline; an index with a BucketCount becomes a hash index. Changes to the MemoryOptimized setting, the Durability value, the inline index set, or a BucketCount are refused by name rather than attempted, because SQL Server has no ALTER for any of them. The database requires a MEMORY_OPTIMIZED_DATA filegroup and In-Memory OLTP support; SchemaSmith fails rather than degrading the table to disk, which would alter concurrency and durability semantics.
  • New Ledger tables — "Ledger": "AppendOnly" or "Updatable" creates a tamper-evident ledger table, and the setting round-trips through extraction. It cannot be combined with IsTemporal — a ledger table manages its own history — and because SQL Server has no ALTER to or from one, a change on a deployed table is refused rather than attempted. Requires SQL Server 2022; below that the table deploys as an ordinary one and the downgrade is reported through UnsupportedFeaturePolicy.
  • New Graph tables — "GraphType": "Node" or "Edge" creates the table AS NODE / AS EDGE and round-trips through extraction. SQL Server has no ALTER that converts a table to or from a graph table, so a change on a deployed table is refused by name. Requires SQL Server 2017, and the graph pseudo-columns SQL Server adds are never extracted and never dropped.
  • New FILESTREAM columns — "FileStream": true on a VARBINARY(MAX) column stores its value as a file on an NTFS filegroup instead of in the row, and FileStreamFileGroup names the table's FILESTREAM_ON filegroup. The table must carry a ROWGUIDCOL column covered by a single-column primary key or unique constraint — a unique index looks equivalent and is not. FILESTREAM has to be enabled on the server and the database first; SchemaSmith creates neither.
Declare PostgreSQL objects you used to script
  • New Sequences — A Sequences/ folder holding .json files declares a sequence's DataType, Increment, bounds, Cache and Cycle, and SchemaSmith alters only what differs, so an unchanged sequence produces no statement. The current value is never managed — it records which numbers have already been handed out, so a deploy that reset it would re-issue keys already in use. Scripted .sql files in the same folder still run exactly as before.
  • New Enum and domain types — Enum Types/ and Domain Types/ folders declare each type in .json and converge it, replacing the guarded CREATE script that quietly stopped doing anything once the object existed. Enum order is preserved because PostgreSQL compares values by declared position, so a value added mid-list lands mid-type; removing one is reported and never performed, since it would mean recreating the type and dropping every column using it. Domain types converge their CheckConstraints, NotNull and Default through ALTER DOMAIN, without dropping the type or touching the columns that use it.
  • New Row-level security policies — A Policies array on a table declares its CREATE POLICY definitions — Name, Permissive, Command, Roles, UsingExpression and WithCheckExpression — and they round-trip through extraction. This completes RowLevelSecurity, which could switch the feature on with no way to declare a policy to go with it. A policy that leaves the package is dropped, with no opt-out flag: a stale policy is a live access-control rule.
Keep MariaDB's temporal tables intact
  • Fix System-versioned tables survive extraction — MariaDB reports a system-versioned table as SYSTEM VERSIONED rather than BASE TABLE, and extraction matched only the latter — so such a table vanished from every extracted package with no error and no warning, and drop-by-absence then ran against a package that was short. The table type is now recognized for both authoring forms, and the engine-owned row-start and row-end columns stay out of the package so a re-deploy never tries to manage columns the engine owns.
  • New Application-time periods — A PERIOD FOR definition — the interval a row's data is valid for, as distinct from system versioning's record of when it was stored — is read into a Periods list on the table, and re-deploying a table that has one no longer fails outright. DropPeriodsRemovedFromProduct removes a period the package has stopped declaring; it defaults to off, because extraction omits Periods entirely on a table that has none, so an older package cannot authorize the removal. Dropping a period leaves its columns and their data untouched.
  • New Opt in before history is rewritten — MariaDB refuses any column change on a system-versioned table unless @@system_versioning_alter_history is KEEP, and KEEP does not merely permit the change — it applies the change to the stored history too, rewriting old rows into a shape they never actually had. That is a data-retention decision, so SystemVersioningAlterHistory leaves it to you: unset, the engine refuses the change exactly as it does today, and the refusal only fires when a change genuinely needs it.
Declare where data lives and how it is stored
  • New SQL Server partition schemes — PartitionScheme and PartitionColumn declare where a table's data lives, and the same pair on an index places it independently — an index is not required to be aligned with its table. The scheme is a name only: SchemaSmith never creates the partition function or scheme, exactly as it never creates a filegroup, and a scheme missing from the target fails by name before any DDL runs. Changing a deployed table's placement is refused, because moving it rewrites every row.
  • New MySQL and MariaDB partitioning — A Partitioning object carries Method (RANGE, LIST, HASH, KEY and the COLUMNS forms), Expression, PartitionCount for HASH and KEY, and an ordered Partitions list for RANGE and LIST, where the order is part of the definition. It is applied on create and round-trips through extraction; a change on a deployed table is refused, since it rewrites every row. A table the package says nothing about is left alone, so a hand-partitioned database still deploys the way it does today.
  • New InnoDB compression options — PageCompressed and PageCompressionLevel declare MariaDB's InnoDB page compression, and MySQL spells its equivalent Compression — each is accepted only on its own engine. KeyBlockSize sets the InnoDB compressed-page size in KB and works on both, though it is only meaningful alongside RowFormat: "COMPRESSED". All of them are applied on create and round-trip through extraction.
Stop losing things you never agreed to lose
  • Enhanced Re-extraction stops reshuffling the package — SchemaTongs sorted every list alphabetically on each extraction, so refreshing a package produced a whole-file diff that buried the one thing that actually changed, and any hand-arranged ordering was lost. Product:PreserveExistingOrder, on by default, keeps the order a file already had for everything still present, appends what is genuinely new, and drops what the database no longer has. Neither it nor Product:ObjectOrder changes a deployment — they decide how the file is written.
  • Fix Change data capture keeps its history — Deploying a column add, drop, or type change to a table with "EnableCDC": true used to disable capture, drop the capture instance and its change table, and re-enable it — losing every row a downstream reader had not yet consumed, silently. A deploy now stands up a second capture instance beside the original, which is SQL Server's own supported pattern, and the log names the old instance so you can retire it once your readers have drained it. Only two capture instances per table exist, so a deploy that would need a third refuses before touching any column.
  • Fix Schema-bound dependencies name themselves — SQL Server refuses to alter a column while a schema-bound view or function references it, and error 4922 says only that "one or more objects access this column", leaving you to go and find which. SchemaSmith now names the blocking module, the column it blocks, and the remedy. Turning on DropSchemaBoundDependents goes further and drops those modules, applies the column change, then recreates them from your package; it stays off by default, because a drop that fired unasked would destroy a scripted object in a package that never opted in.

Mistyped settings now warn instead of vanishing, XML reference-data delivery works on every supported engine, and a long list of unchanged objects finally stop redeploying.

Catch misconfigured settings early
  • New Unrecognized settings are reported — A typo used to be invisible: Target:Sever bound nothing and the run continued exactly as though it had never been set, so a deployment could quietly ignore half its configuration. Each tool now checks the settings it was handed against the settings it actually reads and warns about anything unrecognized, across the settings file, SmithySettings_ environment variables, and command-line overrides alike. It is a warning, not an error — the run continues.
Deliver reference data to legacy targets
  • New XML delivery encoding everywhere — DataDelivery.ContentEncoding: "Xml" is now accepted on every supported platform, not SQL Server alone. On SQL Server the default JSON encoding shreds content with OPENJSON, which needs compatibility level 130, so a database left at 100–120 could not run a JSON delivery at all; the XML path works at every level down to 100. PostgreSQL shreds the payload natively with xmltable(), and MySQL and MariaDB convert it once, up front, then shred it through the ordinary JSON row source.
  • New Extract straight into XML — DataTongs --DeliveryEncoding=Xml now extracts in the XML delivery encoding from any source engine, where it previously warned and downgraded to JSON on anything but SQL Server, and stamps the encoding onto the delivery it configures.
  • Enhanced Delivery takes precedence over merge scripts — When --ConfigureDataDelivery actually configures delivery for a table, DataTongs no longer also emits a merge script for that same table, so one extraction stops producing two competing ways to load it.
Model SQL Server tables more precisely
  • New Column sets — A column declared "IsColumnSet": true deploys as COLUMN_SET FOR ALL_SPARSE_COLUMNS, the XML column that aggregates a table's sparse columns. Available at the SQL Server 2008 floor, alongside Sparse.
  • New Filegroup placement — FileGroup on a table or an index is a filegroup name only, never a file path, so the package stays portable across environments. Leave it unset and SchemaSmith does not manage placement at all. An index with no filegroup of its own follows its table, not the database default — and because an index is declared independently of its table's filegroup, you can keep a large table's data and its indexes on separate storage.
  • New Named temporal history tables — HistoryTableName and HistoryTableSchema point a system-versioned table at a history table other than the default <Name>_Hist in the same schema.
Declare column behavior on MySQL and MariaDB
  • New Auto-refresh on update — "OnUpdateCurrentTimestamp": "CURRENT_TIMESTAMP" deploys a TIMESTAMP or DATETIME column as ... ON UPDATE CURRENT_TIMESTAMP, and an optional fractional-seconds precision round-trips exactly ("CURRENT_TIMESTAMP(3)"). It is independent of Default, which governs the value on INSERT while this governs the refresh on UPDATE — declare either, both, or neither. No version gate applies.
  • New Spatial reference restriction — "Srid": 4326 deploys as col POINT SRID 4326, so the column accepts only geometries in that reference system. MySQL 8.0.3 and above; MariaDB has no equivalent attribute at any version, and the restriction is skipped there.
Stop redeploying objects that never changed
  • Fix PostgreSQL identity and array columns — An identity column declaring its sequence options, and an array column whose type the catalog and the package describe differently, were both re-modified on every single deploy. Each is now reconciled and recognized as unchanged.
  • Fix PostgreSQL index round-trips — An index with a DESC key was re-created on every deploy and extraction never reported the DESC at all; a multi-column index declared the natural way, with a space after the comma ("IndexColumns": "tenant_name, event_time"), was likewise re-created every time.
  • Fix SQL Server check constraints — SQL Server rewrites what you declare, storing [RetentionDays] <= 365 in its own normalized form, so a constraint written the natural way was dropped and re-created on every deploy.
  • Fix SQL Server declared precision — A TIME(n) or DATETIMEOFFSET(n) column was re-altered on every deploy, and an extract-then-deploy round trip silently lost the declared precision.
  • Fix MySQL and MariaDB defaults and prefix indexes — A DECIMAL column with a declared default was re-altered every run, because the engine stores the default at the column's scale and "Default": "0" on a DECIMAL(12,2) never matched it back; a prefix-length index ("IndexColumns": "code(5)"), ordinary practice for indexing a long text column, was rebuilt every run.
  • Fix Reference data on SQL Server 2016 — Data delivery failed outright, because the merge-script build aggregated column lists with STRING_AGG, a SQL Server 2017 function. It now falls back to FOR XML PATH ordered aggregation, so the end state is identical to a modern deployment.

Deploy to the servers you already run — SchemaSmith now targets SQL Server 2008, PostgreSQL 12, and MySQL 5.7, and adds MariaDB as a supported platform.

Deploy to older servers
  • New SQL Server 2008 support — The floor drops from SQL Server 2017 to 2008, compatibility level 130 down to 100. SchemaSmith hands its schema model to the server as JSON (OPENJSON/FOR JSON) at level 130 and above and switches automatically to an XML encoding below it, where OPENJSON is a parse error; Target:CompatEncoding (auto|legacy|modern) overrides the pick.
  • New PostgreSQL 12 support — The floor drops from PostgreSQL 15 to 12, verified against real PostgreSQL 12 and 14 containers.
  • New MySQL 5.7 and MariaDB 10.2 support — MySQL's floor drops from 8.0 to 5.7, and MariaDB is supported from 10.2 up (new in this release — see below), both on one version-agnostic JSON_EXTRACT shred in place of JSON_TABLE. Newer DDL falls back to an equivalent path with the same end state, so a column rename uses CHANGE COLUMN instead of RENAME COLUMN; MySQL 5.6 and MariaDB 10.1 have no JSON support and are rejected.
  • New Unsupported-feature policy — Target:UnsupportedFeaturePolicy decides what happens when a declared feature outruns the target's version, on SQL Server, PostgreSQL, MySQL, and MariaDB alike. It covers cases like NULLS NOT DISTINCT below PostgreSQL 15, CHECK constraints below MySQL 8.0.16, and descending index key parts below MySQL 8.0. The default warn applies the object without the unsupported clause and names it under "Unsupported Feature Downgrades" in the deployment summary with the version it needs; fail aborts pre-emptively instead.
Manage MariaDB schemas
  • New MariaDB support — MariaDB 10.2 and higher is a first-class platform with full MySQL-equivalent coverage across SchemaQuench, SchemaTongs, and DataTongs. Declare "Platform": "MariaDb" in Product.json and packages, tokens, templates, fan-out, checkpoint/resume, and WhatIf all work as they do for MySQL. MariaDB gets its own native DDL generation, so it is a platform in its own right — a package built for MySQL does not deploy to MariaDB, or the reverse. See the MariaDB documentation.
Author for the version you detect
  • New Server version script tokens — Two new automatic tokens, {{ServerMajorVersion}} and {{CompatibilityLevel}}, gate a ShouldApplyExpression or a script body on version with one portable integer comparison ({{CompatibilityLevel}} >= 130) instead of each engine's native version predicate. Gate syntax on {{CompatibilityLevel}} and features on {{ServerMajorVersion}}, since a modern server can host a database left at an old compatibility level; on PostgreSQL, MySQL, and MariaDB the two resolve to the same value, so one expression shape stays portable.
  • New XML data delivery on SQL Server — A DataDelivery can declare "ContentEncoding": "Xml" (default "Json", unchanged), so automatic table-data delivery works at every SQL Server compatibility level, not just the 130 and above that OPENJSON shredding needs. The XML row shape is a documented, stable contract, and SchemaTongs and DataTongs take --DeliveryEncoding=Xml to extract straight into it; SQL Server only, since the other engines have no equivalent cliff.
  • New Detected version in the run log — Pre-flight now logs the engine version it detected and, on SQL Server, the target database's compatibility level, so a version-related diagnosis is self-evident in the log. Covers SchemaQuench per configured server and SchemaTongs' extraction source.
Install with one command, or none at all
  • New winget — winget install SchemaSmith.SchemaSmith puts all four CLI commands on your PATH. The manifest is submitted to microsoft/winget-pkgs each release.
  • New AUR (Arch Linux) — yay -S schemasmith-bin, or any AUR helper, installs all four CLIs from the official release binaries.
  • New Docker image for SchemaQuench — SchemaQuench ships as a multi-arch (linux/amd64 and linux/arm64) image on Docker Hub (schemasmithyfree/schemaquench) and GHCR (ghcr.io/schema-smith/schemaquench), so a deploy runs with no .NET install. Tags are latest, X.Y.Z (immutable), X.Y, and X.
  • New SchemaSmith Deploy GitHub Action — A composite action for running SchemaQuench from a CI/CD pipeline on SQL Server, PostgreSQL, MySQL, and MariaDB, deploying on merge or previewing a run with WhatIf first. It fetches the matching self-contained binary for the runner OS at run time, and pinning @vX.Y.Z pins both the action and the CLI version it runs.
Cross-engine parity & reliability
  • Enhanced Declarative renames beyond SQL Server — OldName now renames a table or column in place on PostgreSQL, MySQL, and MariaDB, preserving its data instead of dropping and recreating the object; previously this worked on SQL Server only. The same deploy also carries the table's own primary key, unique constraint, and index renames, which PostgreSQL used to abort with 42P16: multiple primary keys for table.
  • Fix MySQL and MariaDB re-deploy speed — Re-deploying a product no longer spends minutes in convergence. The foreign-key, index, and table-comparison passes each used to read INFORMATION_SCHEMA once per declared object, in a form the server could not index or push filters down through; INFORMATION_SCHEMA is not a stored table on those engines, so every one of those reads was expensive.
  • Fix SQL Server temporal table round-trip — SchemaTongs extraction now preserves system-versioning. Previously an extract emitted no IsTemporal and re-emitted the period columns (ValidFrom and ValidTo) as ordinary columns, so extract then re-deploy silently dropped system-versioning.

Control what gets dropped, see exactly what a run did, and validate every package before it ships.

Prevent accidental drops
  • New Environment-level PreventDrop — Set PreventDrop: true in SchemaQuench.settings.json (or the SmithySettings_PreventDrop environment variable) and that environment never drops an object for being absent from the package. Withheld drops are itemized in the run summary, and a change that requires dropping and recreating a declared object still applies normally.
  • New Sticky per-table PreventDrop — Mark a table "PreventDrop": true and it is never dropped by absence, even after you delete it from the package. The flag persists in the database itself, as a PreventDrop extended property on SQL Server and, on PostgreSQL and MySQL, a PreventDrop column on the ProductOwnership tracking table, so it survives the table's own removal.
  • Fix SQL Server check-constraint protection — Single-column check constraints now respect drop protection at every cascade tier. Previously DropCheckConstraintsRemovedFromProduct silently failed to protect a named check that referenced only one column.
Track every deployment
  • New Deployment summary report — Every run writes SchemaQuench - Summary.json and SchemaQuench - Summary.md to the log directory, capturing outcome, exit code, duration, per-target results, which migration scripts ran, bottleneck timings, and verified created, modified, and dropped counts per object type.
  • New Failure triage roll-up — When a run fails, SchemaQuench - Failures.log groups every failed scope by phase with its engine error, its resolved-SQL artifact path, and the log lines leading up to it, while a *** FAILED banner marks each one live in the progress stream.
  • Enhanced Resolved-SQL artifacts everywhere — Product-level Before and After scripts, validation scripts, and generated quench DDL now all write a re-runnable resolved-SQL artifact on failure and report it through one Resolved SQL written to: line, honoring ScrubArtifacts redaction like every other failure artifact.
Catch errors early
  • New --Validate static linter — Lint a schema package with no connection, no target, and no side effects, catching malformed files, duplicate objects, dangling references, undefined tokens, and JSON-schema violations. It exits 0 when clean and 2 on any error, so it drops straight into a CI gate.
  • New Canonical table filenames — SchemaTongs now writes each table as <schema>.<table>[.<VariantName>].json, with the schema segment omitted on MySQL and schema-template packages, so a table's variants sort together in source control. A table's identity lives in its content, so a renamed file still deploys; --Validate just emits an SS-FILE-NAME-003 warning naming the canonical form.
Control what goes where
  • New Command-line configuration overrides — Any setting can now be supplied with --Key=value, not just the ones with named switches. Nest with a double underscore (--Target__Server=prod-db) and the override beats the settings file, user secrets, and environment variables.
  • New Gated data deliveries — A table's DataDelivery can now be an array of independently gated deliveries, each with its own ShouldApplyExpression and optional VariantName. Every delivery whose gate passes applies, so you can hold seed data to dev, swap a lean production reference set for a rich one, or layer additive patch slices.
  • New Fleet enumeration from a control database — The new IdentificationDatabase template property re-targets DatabaseIdentificationScript at a control-plane registry database instead of the platform init database. It is token-resolvable, and on PostgreSQL it is the only way to read a registry roster, since a connection there cannot cross databases.
Cross-engine parity & reliability
  • Enhanced Variant-aware re-extraction — When a table or component carries authored variants gated by ShouldApplyExpression, SchemaTongs now evaluates each gate against the source database and folds the extracted shape into the variant that is active there, keeping its gate and variant name. Previously extraction discarded the extracted shape and silently lost real drift.
  • Fix MySQL enum and set values — A column declared enum('web','ios','android') deployed as enum('WEB','IOS','ANDROID'), because type normalization upper-cased the quoted literals along with the keyword. Only the keyword is upper-cased now, and values compare case-sensitively so a corrected declaration converges.
  • Fix PostgreSQL identity and computed columns — A table with a GENERATED … AS IDENTITY column failed to deploy with a repeating syntax error and never converged; identity columns now compare by kind only. Computed columns on a new table also skip the old create-plain-then-drop-and-re-add cycle.

Ship targeted patches, protect what you didn't touch, and deploy safely across engine versions.

Patch delivery
  • New SchemaShears — A supporting patch-delivery tool that carves a deployable patch package from a full schema product using a manifest of changed object paths; objects the manifest omits are preserved on the target rather than dropped, with optional --Zip bundling.
Drop protection
  • New Drop-control cascade — Drop toggles now cascade across environment, product, and template tiers, and a higher tier can hard-lock them off so a production environment suppresses every automatic drop regardless of what a package declares.
  • New Per-object drop gates — Choose whether removed columns, foreign keys, check constraints, statistics, and product-owned indexes are dropped, resolved across the same tiers so any table can tighten protection for its own objects.
Deploy safely across versions
  • New Pre-flight diagnostics — --TestConnection and --PreviewTargets validate every configured server and print a read-only report of the databases and schemas a run would touch, exiting before any change is made.
  • Enhanced MinimumVersion enforcement — SchemaQuench detects each target's engine version and aborts the whole run before touching anything if a target is below the declared version floor (previously the field was metadata only).
  • New Version-adaptive deployment — SchemaSmith detects each target server's version at deploy time and adapts the SQL it generates where engine versions differ, so one package deploys correctly across, for example, PostgreSQL 15, 16, and 17.
Cross-engine parity & reliability
  • New MySQL soft-drop hooks — MySQL gains the same custom table drop and restore hooks SQL Server and PostgreSQL already had, enabling recyclebin-style soft-drop and restore of removed tables.
  • New Always Encrypted safety guard — On SQL Server, a deployment that would re-encrypt data on a populated column now stops before any change and names the exact column, instead of failing partway.
  • Enhanced Conditional-deployment expressions — ShouldApplyExpression now accepts either a bare predicate or a full SELECT on every kind of gate.
  • Fix Idempotency — Repeated deployments no longer churn columns or primary keys over cosmetic type spellings, and cross-template schema tokens now resolve correctly.

Multi-tenant fan-out, conditional deployments, and deployments you can debug.

Multi-tenant & fan-out
  • New Multi-schema fan-out — One template can deploy across many schemas in a single database on SQL Server and PostgreSQL, with the active schema available to your scripts as {{SchemaName}} — a natural fit when each tenant owns its own schema.
  • New Config-driven targets — Define per-environment lists of databases or schemas in settings and let SchemaQuench provision the missing ones — one package, per-environment tenant rosters.
  • New Selective execution scope — Filter a run by template, database, or schema to deploy to a single newly-onboarded tenant without re-running the whole product.
Conditional deployment
  • New Folder-level conditions — Any script folder can carry a ShouldApplyExpression evaluated against the target at deploy time — split engine-specific folders, skip a folder on managed platforms, or keep test data out of production.
  • New Per-script runtime skip — A script can decide at deploy time that it shouldn't apply and be logged as skipped, without failing the deployment.
Debug & protect
  • New Resolved-SQL artifact — When a script fails, the exact expanded SQL the server rejected is written to a re-runnable file, its path shown in the log, with an optional scrubbed variant safe to attach to support tickets.
  • New Log hygiene — Logs now mask sensitive values — passwords, secrets, API keys, connection strings — by name and strip embedded credentials from connection strings, so CI artifacts and screenshots don't leak secrets.

One free product, three platforms, one source tree.

One Product, Three Tools
  • New One free product, three platforms — SchemaSmith covers SQL Server, PostgreSQL, and MySQL from a shared codebase under SSCL v2.0. Free for any purpose including commercial use, with no restrictions on organization size, revenue, or environment count. The code is on GitHub for anyone to read
  • New Three tools, one workflow — SchemaTongs, SchemaQuench, and DataTongs work across all three platforms with platform-specific adapters and native DDL output. Learn once, deploy on whichever engine you run
Schema Modeling
  • New Indexed and materialized view support — SQL Server indexed views and PostgreSQL materialized views with full index management. Index-only changes skip the view rebuild
  • New Custom properties via Extensions — Attach your own metadata to any table, column, index, foreign key, or view. Custom fields are queryable from your scripts via auto-tokens, so you can drive replication, environment behavior, validation, and audit metadata from the same JSON your schema lives in
  • New Platform-specific types — Native modeling for PostgreSQL (exclude constraints, range types, materialized views) and MySQL (multi-column full-text indexes, generated columns, tablespaces). No more lowest-common-denominator schemas
Deploy Smarter
  • New Checkpoint and resume — --ResumeQuench picks up after a failed run and skips everything that already completed. No more re-running the first 50 migrations because the 51st failed
  • New FK-aware data delivery — Declare a DataDelivery block on a table and SchemaSmith handles foreign-key dependency ordering and nullable FK columns automatically. Hand-authored merge scripts go away
  • New Conditional deployment (ShouldApplyExpression) — Templates carry SQL expressions evaluated at runtime. Deploy different schemas to dev, test, and prod from the same package
  • New Multi-server deployment + custom script folders — Push the same product to multiple server instances in one run, and define your own script execution slots beyond the built-in folder structure
  • New Universal token resolution — {{TokenName}} resolves in every script (Before/After, objects, migrations, data delivery), with environment-variable overrides. Advanced tags pull values from inline queries, files, binary contents, or full schema JSON. One package parameterizes cleanly across every environment
  • New Datafix-only deployments — KindleTheForge, UpdateTables, and DropTablesRemovedFromProduct toggles let you run partial-package deployments — data fixes without schema churn, or schema-only without touching reference data
Install Anywhere
  • New Self-contained, signed executables — Single-file builds for Windows, macOS, and Linux on x64 and arm64. Zero .NET runtime required. Windows binaries are Authenticode-signed, so SmartScreen warnings are gone. Runs on minimal Linux containers without libicu
  • New Native package managers — choco install schemasmith on Windows. .deb and .rpm packages for Debian, Ubuntu, RHEL, Fedora, and Amazon Linux. One install puts all three CLI commands on your PATH

Community License v2.0: No Restrictions on Organization Size or Revenue

SQL Server Community
  • License The Community Edition is now licensed under SSCL v2.0: free for any purpose (personal, commercial, internal, production) with no restrictions on organization size, revenue, database scope, or number of environments. You cannot distribute SchemaSmith to others or operate it as an ongoing managed service for others. Setup and configuration services are permitted. Whether you're at a startup or an enterprise, the Community Edition now works at any scale, no organization size or revenue restrictions. Read the full license

License file integration, checkpoint-based deployment recovery, and five new SchemaHammer UI features strengthen reliability and streamline workflow management across all editions.

SQL Server Community v1.1.8
  • Fix SQL batch parsing now handles single quotes inside bracketed identifiers
  • Fix Foreign key comparison correctly identifies ON DELETE and ON UPDATE actions
  • Fix Fulltext index detection now captures TYPE COLUMN in existing index comparison
SQL Server Enterprise v1.2.2

Includes all Community fixes above, plus:

  • New License file integration — Encrypted license file support with automatic search path
  • New Checkpointing and Resume — Save quench progress to checkpoint files; resume interrupted deployments
  • New DeliverData appsetting — Make the automatic Data Delivery step optional
  • New VerboseLogging appsetting — Include PRINT messages in logged output
  • New SchemaHammer: Template creation — Create new templates with default folder structure from context menu
  • New SchemaHammer: Script folder sync — Adding or removing template folders auto-creates directories and tree nodes
  • New SchemaHammer: Token preview — Preview resolved query token values against the quench server
  • New SchemaHammer: Search expansion — Expand token values when searching code
  • New SchemaHammer: File picker — Browse for file-based script tokens instead of manual path entry
  • Enhanced WhatIf mode — Scripts and data delivery steps now logged for better dry-run output
  • Enhanced Tool-specific help — Each tool displays its own relevant command line switches
PostgreSQL Enterprise v1.0.2
  • New License file integration — Encrypted license file support with automatic search path
  • New Checkpointing and Resume — Save quench progress and resume interrupted deployments
  • New DeliverData appsetting — Make Data Delivery optional
  • New SchemaHammer enhancements — Template creation, folder sync, token preview, search expansion, file picker
  • Enhanced WhatIf mode improvements and tool-specific help
  • Enhanced Platform validation — Graceful error when using the wrong platform's toolset
MySQL Enterprise v1.0.0 Initial Release
  • New SchemaSmith for MySQL — Full MySQL 8.0+ support for metadata-driven schema management
  • New SchemaHammer — Visual editor for MySQL schema templates
  • New SchemaQuench — Automated deployment engine for MySQL databases
  • New SchemaTongs — Extract existing MySQL database schemas into templates
  • New DataTongs — Data extraction and delivery for MySQL
  • New License file integration, checkpointing, and resume support
  • New Events, generated columns, and AUTO_INCREMENT management
  • New InnoDB storage engine optimization and table options
  • New REPLACE INTO, INSERT ON DUPLICATE KEY UPDATE, and INSERT IGNORE data delivery
Ask Forge v1.0.1 Initial Release
  • New AI-powered CLI agent — Conversational schema management with agentic LLM workflows across SQL Server, PostgreSQL, and MySQL
  • New MCP server — Expose 46 schema tools to Claude Desktop, VS Code, Cursor, and other MCP clients
  • New 46 tools across 4 tiers — Read-only exploration, generation, modification, and external tool execution
  • New 10 LLM providers — Ollama, OpenAI, Anthropic, Azure OpenAI, Google Gemini, Groq, Mistral, DeepSeek, xAI, and custom endpoints
  • New Trust levels — Observer, Assistant, and Operator tiers control tool access with confirmation gates
  • New Interactive REPL and single commands — Persistent console sessions or one-off CLI commands for scripting and automation
  • New Schema generation from natural language — Describe what you need and Ask Forge generates platform-specific schema JSON
  • New Migration script generation — Automated migration planning with step-by-step SQL scripts
  • New Data validation tools — Detect nulls, orphaned foreign keys, duplicates, and data type mismatches
  • New 30-article knowledge base — Embedded articles covering architecture, best practices, and troubleshooting

Refined DataTongs configuration and improved PostgreSQL type handling deliver cleaner error messages and more precise data extraction for enterprise workflows.

SQL Server Community v1.1.7
  • Enhanced Simplified DataTongs configuration to reduce confusing errors and edge cases
  • Enhanced Streamlined binary distribution for easier downloads
SQL Server Enterprise v1.2.1

Includes all Community changes above, plus:

  • Enhanced Improved error messages when table or schema names contain typos
PostgreSQL Enterprise v1.0.1

Includes shared changes above, plus:

  • Fix Virtual column flag correctly handled during schema extraction
  • Fix BPCHAR type correctly mapped when extracting table definitions
  • Fix Unconstrained numeric types handled properly
  • Fix User-defined type length modifiers no longer added erroneously during extraction

PostgreSQL Enterprise edition launches alongside table import capabilities and limited patch mode, expanding SchemaSmith's reach across database platforms.

SQL Server Community v1.1.6
  • Enhanced Platform identification added to product metadata and version output
  • Enhanced Error when using the wrong platform's toolset for a product
SQL Server Enterprise v1.2.0

Includes all Community changes above, plus:

  • New SchemaHammer: Table import — Import existing database tables into a product template
  • New Limited patch mode — Run only patches and data fixes by disabling table updates and kindling
  • New Run scripts twice option — Execute scripts a second time for two-pass deployment scenarios
  • Enhanced Preserve custom properties and ShouldApplyExpression when re-extracting tables
  • Enhanced Preserve data delivery options when re-extracting tables
  • Fix Index-only mode now correctly sets product ownership
  • Fix Minor SchemaHammer UI fixes for adding table components
PostgreSQL Enterprise v1.0.0 Initial Release
  • New SchemaSmith for PostgreSQL — Full PostgreSQL support for schema management
  • New SchemaHammer — Visual editor for PostgreSQL schema templates
  • New SchemaQuench — Automated deployment engine for PostgreSQL databases
  • New SchemaTongs — Extract existing PostgreSQL database schemas into templates
  • New DataTongs — Data extraction and delivery for PostgreSQL
  • New Expression column support for index definitions
  • New WITHOUT OVERLAPS support for unique and primary key constraints
  • New Statistics management and exclude constraints
  • New Fill factor management for tables and indexes
  • New Cluster index updates
  • New Older PostgreSQL version compatibility

Targeted fixes for data handling and delivery reliability round out the fall release cycle.

SQL Server Community v1.1.5
  • Fix TEXT, NTEXT, and IMAGE column handling fixed in DataTongs
SQL Server Enterprise v1.1.5

Includes all Community fixes above, plus:

  • Fix Data delivery behavior and missing default folder fixes

Table and column rename support, expanded CLI flexibility, and streamlined installers forge a more powerful and accessible schema management experience.

SQL Server Community v1.1.3–v1.1.4
  • New Table and column renames — SchemaQuench can now handle table and column rename operations
  • New --ConfigFile switch — Specify an alternate appsettings configuration file
  • New --Version switch — Display version information from the command line
  • New --LogPath switch — Specify a custom path for log file output
  • New Zipped package support — Quench directly from a zipped schema package
  • New Combined MSI installers — Single installer packages all CLI tools together
  • Enhanced New SCHEMASMITH_ environment variable prefix for configuration
  • Fix Table trigger name comparison corrected
SQL Server Enterprise v1.1.3–v1.1.4

Includes all Community changes above, plus:

  • New DataTongs export column list — Specify which columns to include in data exports
  • Enhanced Template load performance improvements in SchemaHammer
  • Enhanced Preserve custom properties and data delivery options when re-extracting tables

Foundation release introduces DataTongs trigger controls, Docker containerization support, and core stability improvements for production-ready deployments.

SQL Server Community v1.1.0–v1.1.2
  • New DataTongs trigger control — Option to disable triggers during data load operations
  • Enhanced Docker build support improvements
  • Fix DataTongs SQL script corrections
SQL Server Enterprise v1.1.0–v1.1.2

Includes all Community changes above, plus:

  • Enhanced Data delivery integration tests and reliability improvements

Shape. Strengthen. Succeed.

Free schema-as-code for SQL Server, PostgreSQL, MySQL, and MariaDB.

The source is on GitHub for anyone to read.

Get Started on GitHub