September 9, 2019
Skeema v1.3.0 has been released! This new version primarily focuses on significant enhancements to Skeema’s linter, allowing users to customize the safeguards in their schema change workflow.
Lint on skeema diff and skeema push
Previously, Skeema’s linter logic was only available by running skeema lint, which lints entire schema directories. If you have known problems in pre-existing tables that aren’t being changed, skeema lint will remind you every time, which quickly becomes tedious. And if you forget to run skeema lint at all, you may accidentally make problematic changes, as there was no lint-related safeguard built in to skeema push previously.
Skeema v1.3.0 fixes this by having skeema diff and skeema push automatically run linter checks, but only on objects (tables, procs, funcs) that actually have changes in the diff. If any of the triggered linter checks have been configured to the warning level, this will be displayed on STDERR, but doesn’t otherwise affect the operation. However, if any of the triggered linter checks have been configured to the error level, this will prevent the operation from proceeding for the current instance / schema pair, and affects the overall exit code accordingly.
In combination, this feature permits powerful configurable guardrails for your schema change process. For example, if your company bans use of foreign keys, you could set lint-has-fk=error in a top-level .skeema file; this way, any attempt to skeema push a table with foreign keys will throw an error.
Users who wish to disable this feature may use skip-lint, either permanently (adding skip-lint to a .skeema file) or on an as-needed basis (e.g. skeema push --skip-lint on the command-line). Users can also override individual linter options on the command-line as needed, for example running skeema push --skip-lint-charset (or equivalently skeema push --lint-charset=ignore) if you need to intentionally bypass the lint-charset check just for one specific manual push.
New linter checks
Skeema v1.3 includes 7 new configurable linter checks, in addition to the 3 checks introduced in v1.2. Each check now has its own enum option, which can be set to either “ignore” (skip the check), “warning” (generate non-fatal output if the check is triggered), or “error” (fatal if the check is triggered). The new checks include:
lint-dupe-indexchecks for redundant indexes- This includes indexes that are completely identical, as well as indexes that are a subset of another index
- Redundant indexes consume disk space and harm write performance
lint-auto-increstricts which column types may be used for auto_increment columns, along with matching optionallow-auto-inc- Designed for users with large tables, e.g. set
allow-auto-inc=bigint unsignedto prevent use of smaller int types that have risk of ID space exhaustion - Or, for users who wish to flag/ban auto_increment entirely, simply set
allow-auto-inc=''
- Designed for users with large tables, e.g. set
lint-definerrestricts what proc/func definers may be used, along with matching optionallow-definerto specify the valid definer user@host patterns- Designed for users who require non-root routine definers for security purposes
- This defaults to being fully permissive of any definer, as
allow-definerdefaults to “%@%”, a pattern matching all possible users; overrideallow-definerto control this
lint-display-widthchecks for int columns with nonstandard display width values- Display widths rarely have any effect, and are a common source of confusion to MySQL users
lint-has-fkoptionally flags any use of foreign keys- This check is disabled by default, but users who prohibit foreign keys entirely can enable it
lint-has-routineoptionally flags any use of stored procedures and functions- This check is disabled by default, but users who prohibit routines entirely can enable it
lint-has-timeoptionally flags any use of temporal column types- This check is disabled by default, but users who prefer storing UTC timestamps using simple int types can enable it
The 3 previous lint checks are now configured using new separate options:
lint-pkchecks for tables lacking a primary keylint-charsetchecks for table columns that are using a character set that isn’t listed in the matching optionallow-charsetlint-engineflags tables that are using a storage engine that isn’t listed in the matching optionallow-engine
CI system improvements
The Skeema Cloud Linter also fully includes the above linter changes.
Whenever a new commit or pull request occurs, only the modified objects will be linted and annotated by the CI system, rather than the entire schema repo. This cuts down on extraneous output, and also makes the system more usable in monorepos that combine code and schemas in the same repository.
All 10 of the CLI’s configurable linter rules are available in Cloud Linter, providing instant feedback on schema change pull requests. If you store your schema repo on GitHub.com, give the system a try today – there’s no charge for personal accounts, and organization accounts may sign up for a free trial.
New skeema format command
Prior to Skeema v1.2, the skeema lint command was mostly just a formatter, to align CREATE statements in *.sql files with the canonical format shown in SHOW CREATE commands. The linter still retains this ability, but as its other functionality has matured in recent releases, it now makes sense to also offer a separate command that only performs formatting: skeema format.
For users who want to enforce standardized formatting of their *.sql files, the formatter can also be used as a verification step in CI/CD pipelines by running skeema format --skip-write. This will only return a 0 exit code if all files are formatted properly, but it won’t actually rewrite any files itself.
Finally, users may now optionally skip the formatting step of linting or pulling by using skeema lint --skip-format or skeema pull --skip-format, respectively.
Other enhancements
Two other notable improvements to what Skeema supports:
- Tables using FULLTEXT indexes can now be diff’ed using
skeema diffandskeema push. - MariaDB 10.4, which was released in June, is now fully supported.