{"id":13412043,"url":"https://github.com/muir/libschema","last_synced_at":"2026-05-06T18:01:51.869Z","repository":{"id":38316669,"uuid":"383254478","full_name":"muir/libschema","owner":"muir","description":"database schema migrations on a per-library basis [Go]","archived":false,"fork":false,"pushed_at":"2025-12-19T06:05:10.000Z","size":418,"stargazers_count":17,"open_issues_count":2,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-21T22:50:53.287Z","etag":null,"topics":["database","database-migrations","golang","mysql","postgresql","singlestore"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/muir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-07-05T20:13:45.000Z","updated_at":"2025-12-18T23:05:10.000Z","dependencies_parsed_at":"2024-06-19T16:22:59.464Z","dependency_job_id":"38922580-5b21-4979-a88b-e0a5f2d32ff3","html_url":"https://github.com/muir/libschema","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/muir/libschema","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muir%2Flibschema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muir%2Flibschema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muir%2Flibschema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muir%2Flibschema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/muir","download_url":"https://codeload.github.com/muir/libschema/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muir%2Flibschema/sbom","scorecard":{"id":667631,"data":{"date":"2025-08-20T22:41:50Z","repo":{"name":"github.com/muir/libschema","commit":"50934ac946ef8c4cae19d3f15ab0292e51d38a84"},"scorecard":{"version":"v5.2.1","commit":"ab2f6e92482462fe66246d9e32f642855a691dc1"},"score":7,"checks":[{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dependency-update-tool"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/6 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":8,"reason":"dependency not pinned by hash detected -- score normalized to 8","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/codecov.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/muir/libschema/codecov.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/mysql.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/muir/libschema/mysql.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pg.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/muir/libschema/pg.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/s2.yml:60: update your workflow using https://app.stepsecurity.io/secureworkflow/muir/libschema/s2.yml/main?enable=pin","Info:  20 out of  20 GitHub-owned GitHubAction dependencies pinned","Info:  11 out of  15 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#packaging"}},{"name":"Maintained","score":6,"reason":"8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/codacy-analysis.yml:26","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:32","Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:31","Info: jobLevel 'contents' permission set to 'read': .github/workflows/golangci-lint.yml:9","Info: jobLevel 'pull-requests' permission set to 'read': .github/workflows/golangci-lint.yml:10","Info: jobLevel 'contents' permission set to 'read': .github/workflows/scorecards.yml:23","Info: jobLevel 'actions' permission set to 'read': .github/workflows/scorecards.yml:24","Info: topLevel 'contents' permission set to 'read': .github/workflows/codacy-analysis.yml:21","Info: topLevel 'contents' permission set to 'read': .github/workflows/codecov.yml:6","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:24","Info: topLevel 'contents' permission set to 'read': .github/workflows/go.yml:4","Info: topLevel 'contents' permission set to 'read': .github/workflows/golangci-lint.yml:4","Info: topLevel 'contents' permission set to 'read': .github/workflows/mysql.yml:5","Info: topLevel 'contents' permission set to 'read': .github/workflows/pg.yml:5","Info: topLevel 'contents' permission set to 'read': .github/workflows/s2.yml:5","Info: topLevel permissions set to 'read-all': .github/workflows/scorecards.yml:11","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":2,"reason":"badge detected: InProgress","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: all commits (30) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#sast"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#signed-releases"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#security-policy"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#branch-protection"}},{"name":"Contributors","score":3,"reason":"project has 1 contributing companies or organizations -- score normalized to 3","details":["Info: found contributions from: singlestore"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"29 out of 29 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#ci-tests"}}]},"last_synced_at":"2025-08-21T18:39:55.241Z","repository_id":38316669,"created_at":"2025-08-21T18:39:55.241Z","updated_at":"2025-08-21T18:39:55.241Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","database-migrations","golang","mysql","postgresql","singlestore"],"created_at":"2024-07-30T20:01:20.424Z","updated_at":"2026-01-12T12:50:18.336Z","avatar_url":"https://github.com/muir.png","language":"Go","funding_links":[],"categories":["数据库","Database","Data Integration Frameworks","Generators"],"sub_categories":["数据库模式迁移","Database Schema Migration"],"readme":"\n# libschema - database schema migration for libraries\n\n[![GoDoc](https://godoc.org/github.com/muir/libschema?status.png)](https://pkg.go.dev/github.com/muir/libschema)\n![unit tests](https://github.com/muir/libschema/actions/workflows/go.yml/badge.svg)\n![pg tests](https://github.com/muir/libschema/actions/workflows/pg.yml/badge.svg)\n![mysql tests](https://github.com/muir/libschema/actions/workflows/mysql.yml/badge.svg)\n![singlestore tests](https://github.com/muir/libschema/actions/workflows/s2.yml/badge.svg)\n[![report card](https://goreportcard.com/badge/github.com/muir/libschema)](https://goreportcard.com/report/github.com/muir/libschema)\n[![codecov](https://codecov.io/gh/muir/libschema/branch/main/graph/badge.svg)](https://codecov.io/gh/muir/libschema)\n\nInstall:\n\n\tgo get github.com/muir/libschema\n\n---\n\n## Libraries\n\nLibschema provides a way for Go libraries to manage their own database migrations.\n\nTying migrations to libraries supports two things: the first is\nsource code locality: the migrations can be next to the code that\nuses the tables that the migrations address.\n\nThe second is support for migrations in third-party libraries. This\nis a relatively unexplored and unsolved problem: how can an open\nsource (or proprietary) library specify and maintain a database\nschema? Libschema hopes to start solving this problem. \n\n## Register and execute\n\nMigrations are registered:\n\n```go\nschema := libschema.New(ctx, libschema.Options{})\n\nsqlDB, err := sql.Open(\"postgres\", \"....\")\n\ndatabase, err := lspostgres.New(logger, \"main-db\", schema, sqlDB) \n// or\ndatabase, singlestoreHelper, err := lssinglestore.New(logger, \"main-db\", schema, sqlDB)\n// or\ndatabase, mysqlHelper, err := lssinglestore.New(logger, \"main-db\", schema, sqlDB)\n\ndatabase.Migrations(\"MyLibrary\",\n\tlspostgres.Script(\"createUserTable\", `\n\t\tCREATE TABLE users (\n\t\t\tname\ttext,\n\t\t\tid\tbigint\n\t\t)`\n\t}),\n\tlspostgres.Script(\"addLastLogin\", `\n\t\tALTER TABLE users\n\t\t\tADD COLUMN last_login timestamp\n\t\t`\n\t}),\n)\n```\n\nMigrations are then run run later in the order that they were registered.\n\n```go\nerr := schema.Migrate(context)\n```\n\n## Computed Migrations\n\nMigrations may be SQL strings or migrations can be done in Go:\n\n```go\ndatabase.Migrations(\"MyLibrary\", \n\tlspostgres.Computed(\"importUsers\", func(_ context.Context, _ Migration, tx *sql.Tx) error {\n\t\t// code to import users here\n\t}),\n)\n```\n\n## Asynchronous migrations \n\nThe normal mode for migrations is to run the migrations synchronously\nwhen `schema.Migrate()` is called.  Asynchronous migrations are\nstarted when `schema.Migrate()` is called but they're run in the\nbackground in a go-routine.  If there are later migrations, after\nthe asynchronous migration, they'll force the asynchronous migration\nto be synchronous unless they're also asynchronous.\n\n## Version blocking\n\nMigrations can be tied to specific code versions so that they are\nnot run until conditions are met.  This is done with `SkipRemainingIf`.\nThis be used to backfill data.\n\n```go\ndatabase.Migrations(\"MyLibrary\",\n\t...\n\tlspostgres.Script(\"addColumn\", `\n\t\t\tALTER TABLE users\n\t\t\t\tADD COLUMN rating`,\n\tlibschema.SkipThisAndFollowingIf(func() bool {\n\t\treturn semver.Compare(version(), \"3.11.3\") \u003c 1\n\t})),\n\tlspostgres.Script(\"fillInRatings\", `\n\t\t\tUPDATE\tusers\n\t\t\tSET\trating = ...\n\t\t\tWHERE\trating IS NULL;\n\n\t\t\tALTER TABLE users\n\t\t\t\tMODIFY COLUMN rating SET NOT NULL;`,\n\tlibschema.Asychronous),\n)\n```\n\n## Cross-library dependencies\n\nAlthough it is best if the schema from one library is independent\nof the schema for another, sometimes that's not possible, especially\nif you want to enforce foriegn key constraints.\n\nUse `After()` to specify a cross-library dependency.\n\n```go\ndatabase.Migrations(\"users\",\n\t...\n\tlspostgres.Script(\"addOrg\", `\n\t\t\tALTER TABLE users\n\t\t\t\tADD COLUMN org TEXT,\n\t\t\t\tADD ADD CONSTRAINT orgfk FOREIGN KEY (org)\n\t\t\t\t\tREFERENCES org (name) `, \n\t\tlibschema.After(\"orgs\", \"createOrgTable\")),\n)\n\ndatabase.Migrations(\"orgs\",\n\t...\n\tlspostgres.Script(\"createOrgTable\", `\n\t\t...\n\t`),\n)\n```\n\n## Transactions\n\nFor databases that support transactions on metadata, all migrations\nwill be wrapped with a `BEGIN` and `COMMIT`.  For databases that\ndo not support transactions on metadata, migrations will be split\ninto individual commands and run one at a time.  If only some of\nthe commands succeed, the migration will be marked as partially\ncomplete.  If the migration is revised, then the later parts can\nbe re-tried as long as the earlier parts are not modified.  This\ndoes not apply to `Compute()`ed migrations.\n\n### PostgreSQL non-transactional (idempotent) DDL\n\nSome PostgreSQL statements (e.g. `CREATE INDEX CONCURRENTLY`, `DROP\nINDEX CONCURRENTLY`, `REFRESH MATERIALIZED VIEW CONCURRENTLY`)\ncannot run inside an explicit transaction block. Libschema auto-detects\ncommon patterns in `Script(...)` and will execute those outside a\ntransaction; you can also opt in explicitly by using a generic type\nthat is *not* a `*sql.Tx` (e.g. `Generate[*sql.DB]`). Non-transactional\nmigrations must be idempotent: safe to retry after partial failure.\nA fuller rationale, supported patterns, and enum/value guidance\nlive in `lspostgres/NON_TRANSACTIONAL.md`.\n\n### RepeatUntilNoOp (brief)\n\n`RepeatUntilNoOp()` re-runs a single DML statement until\n`RowsAffected()==0`. Use only for pure data updates where the driver\nreports accurate counts. Avoid DDL, guarded `CREATE ... IF NOT\nEXISTS`, concurrent index / materialized view commands, or\nmulti-statement scripts. For anything more complex, prefer a\n`Computed` migration and loop explicitly. See the Go doc comment\non `RepeatUntilNoOp` for detailed guidance.\n\n## Command line\n\nThe `OverrideOptions` can be added as command line flags that \nchange the behavior of calling `schema.Migrate()`\n\t\n\t--migrate-only\t\t\tCall os.Exit() after completing migrations\n\t--migrate-database\t\tMigrate only one logical database (must match NewDatabase)\n\t--migrate-dsn\t\t\tOverride *sql.DB \n\t--no-migrate\t\t\tSkip all migrations\n\t--error-if-migrate-needed\tReturn error if there are outstanding synchronous migrations\n\t--migrate-all-synchronously\tTreat asychronous migrations as synchronous\n\n## Ordering and pull requests\n\nMigrations are run the order that they're defined.  If the set of\nmigrations is updated so that there are new migrations that are\nearlier in the table than migrations that have already run, this\nis not considered an error and the new migrations will be run anyway.\nThis allows multiple branches of code with migrations to be merged\ninto a combined branch without hassle.\n\nMigrations can have explicit dependencies and these dependencies\ncan cross between libraries so that one library's migrations can\ndepend on anothers.\n\n## Code structure\n\nRegistering the migrations before executing them is easier if using\nlibrary singletons.  Library singletons can be supported by using\n[nserve](https://github.com/muir/nject/nserve) or\n[fx](https://github.com/uber-go/fx).  With nserve, migrations can\nbe given their own hook.\n\n## Driver inclusion and database support\n\nLike database/sql, libschema requires database-specific drivers:\n\n- PostgreSQL support is in `\"github.com/muir/libschema/lspostgres\"`\n- MySQL support in `\"github.com/muir/libschema/lsmysql\"`\n- SingleStore support `\"github.com/muir/libschema/lssinglestore\"`\n\nlibschema currently supports: PostgreSQL, SingleStore, MySQL.\nIt is relatively easy to add additional databases.\n\n## Forward only\n\nLibschema does not support reverse migrations.  If you need to fix\na migration, fix forward.  The history behind this is that reverse\nmigrations are rarely the right answer for production systems and\nthe extra work for maintaining reverse migrations is does not have\nenough of a payoff during development to be worth the effort.\n\nOne way to get the benefits of reverse migrations for development\nis to put enough enough reverse migrations to reverse to the last\nproduction schema at the end of the migration list but protected\nby a gateway:\n\n```go\nlibschema.SkipThisAndRemainingIf(func() bool {\n\treturn os.Getenv(\"LIBMIGRATE_REVERSE_TO_PROD\") != \"true\"\n}),\n```\n\nThis set of reverse migrations would always be small since it would\njust be enough to take you back to the current production release.\n\n## Patterns for applying migrations\n\nWhen using a migration tool like libschema there are several\nreasonable patterns one can follow to apply migrations to produciton\ncode.\n\n### Down-Up deploys\n\nThe simplist pattern is to deploy migrations synchronously when\nrolling out updates.  If you take your service down to do deploys\nthen your migrations do not have to be backwards compatible.  This\nhas the huge upside of allowing your schema to eveolve easily and\navoid the build up of technical debt.  For example, if you have a\ncolumn whose name is sub-optimal, you can simply rename it and \nchange the code that uses it at the same time.\n\nTo minimimize downtime so that the downtime doesn't matter in\npractice, run expensive migrations asynchronously.  Asychronous\nmigrations are harder to define because they should be broken up\ninto a whole bunch of smallish transactions.  The `RepeatUntilNoOp()`\ndecorator may be useful.\n\n### Green-Blue deploys\n\nWhen you decide to run without downtime, one consequence is that\nall migrations must be backwards compatible with the deployed\ncode.\n\nDDL operations that are backwards compatible include:\n\n- adding a column, table, or view\n- removing a column, table, or view that is no longer accessed\n- adding a default value to a column\n- remvoing a constraint\n- adding a constraint as long as there are no violations and won't be any new ones\n\nFrom a coding point-of-view, the simplest way to manage developing\nwith these restrictions is to separate the migration into a separate\npull request from any other code changes.  Tests must still pass in\nthe pull request that just has the migration. Local and CI testing\nshould apply the migration and validate that the the existing code\nisn't broken by the change in database schema.\n\nOnly after the migration has been deployed can code that uses the \nmigration be deployed.  When using git, this can be done by having\nlayered side branches: \n\n```mermaid\ngraph LR;\n mob(migration-only branch)\n code(code branch)\n cleanup(cleanup migration branch)\n main --\u003e mob --\u003e code --\u003e cleanup;\n```\n\n### Kubernetes and slow migrations\n\nOne issue with using libschema to deploy changes is that servers can take\na long time to come up if there are expensive migrations that need to be\ndeployed first.  A solution for this is to use `OverrideOptions` to separate\nthe migrations into a separate step and run them in an \n[init container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).\n\nTo do this use the `MigrateOnly` / `--migrate-only` option on your main program\nwhen running it in the init container.\n\nThen use the `ErrorIfMigrateNeeded` / `--error-if-migrate-needed` option on your main\nprogram when it starts up for normal use.\n\n## Code Stability\n\nLibschema is still subject to changes.  Anything that is not backwards compatible\nwill be clearly documented and will fail in a way that does not cause hidden problems.\nFor example, switching from using \"flag\" to using OverrideOptions will trigger\nan obvious breakage if you try to use a flag that no longer works.\n\nAnticipated changes:\n\n- API tweaks\n- Support for additional databases\n- Support for additional logging APIs\n- Support for tracing spans (per migration)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuir%2Flibschema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmuir%2Flibschema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuir%2Flibschema/lists"}