{"id":13412033,"url":"https://github.com/pressly/goose","last_synced_at":"2025-09-09T20:18:20.832Z","repository":{"id":37285205,"uuid":"52555254","full_name":"pressly/goose","owner":"pressly","description":"A database migration tool. Supports SQL migrations and Go functions. ","archived":false,"fork":false,"pushed_at":"2025-09-06T00:01:05.000Z","size":11790,"stargazers_count":9080,"open_issues_count":106,"forks_count":598,"subscribers_count":61,"default_branch":"main","last_synced_at":"2025-09-07T00:47:27.005Z","etag":null,"topics":["database","database-migrations","go","golang","migration","migrations","mysql","postgres","postgresql","schema","sql","sqlite"],"latest_commit_sha":null,"homepage":"http://pressly.github.io/goose/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pressly.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-02-25T20:39:37.000Z","updated_at":"2025-09-06T22:05:01.000Z","dependencies_parsed_at":"2023-11-07T14:42:49.863Z","dependency_job_id":"93b08be9-52b7-487d-8095-6d4521b693ec","html_url":"https://github.com/pressly/goose","commit_stats":{"total_commits":655,"total_committers":125,"mean_commits":5.24,"dds":0.6885496183206107,"last_synced_commit":"483081e10eaf80c1566e3a983f28c156293fcf0d"},"previous_names":[],"tags_count":67,"template":false,"template_full_name":null,"purl":"pkg:github/pressly/goose","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressly%2Fgoose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressly%2Fgoose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressly%2Fgoose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressly%2Fgoose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pressly","download_url":"https://codeload.github.com/pressly/goose/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressly%2Fgoose/sbom","scorecard":{"id":744669,"data":{"date":"2025-08-11","repo":{"name":"github.com/pressly/goose","commit":"bdac41fec4b9bd9b6afae2e65ff7d783ba4d7f77"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.5,"checks":[{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yaml:1","Warn: no topLevel permission defined: .github/workflows/integration.yaml:1","Warn: no topLevel permission defined: .github/workflows/lint.yaml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yaml:7","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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":3,"reason":"Found 8/25 approved changesets -- score normalized to 3","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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"7 commit(s) and 11 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/ci.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/ci.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yaml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/ci.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/integration.yaml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/integration.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/integration.yaml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/integration.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yaml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/lint.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yaml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/lint.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/lint.yaml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/lint.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/release.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/pressly/goose/release.yaml/main?enable=pin","Warn: goCommand not pinned by hash: .github/workflows/ci.yaml:41","Warn: goCommand not pinned by hash: .github/workflows/integration.yaml:28","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned","Info:   0 out of   2 goCommand 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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v3.24.3 not signed: https://api.github.com/repos/pressly/goose/releases/216902726","Warn: release artifact v3.24.2 not signed: https://api.github.com/repos/pressly/goose/releases/208837699","Warn: release artifact v3.24.1 not signed: https://api.github.com/repos/pressly/goose/releases/193508590","Warn: release artifact v3.24.0 not signed: https://api.github.com/repos/pressly/goose/releases/191696917","Warn: release artifact v3.23.1 not signed: https://api.github.com/repos/pressly/goose/releases/190459763","Warn: release artifact v3.24.3 does not have provenance: https://api.github.com/repos/pressly/goose/releases/216902726","Warn: release artifact v3.24.2 does not have provenance: https://api.github.com/repos/pressly/goose/releases/208837699","Warn: release artifact v3.24.1 does not have provenance: https://api.github.com/repos/pressly/goose/releases/193508590","Warn: release artifact v3.24.0 does not have provenance: https://api.github.com/repos/pressly/goose/releases/191696917","Warn: release artifact v3.23.1 does not have provenance: https://api.github.com/repos/pressly/goose/releases/190459763"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/ci.yaml:14"],"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T18:23:08.680Z","repository_id":37285205,"created_at":"2025-08-22T18:23:08.680Z","updated_at":"2025-08-22T18:23:08.680Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274357282,"owners_count":25270674,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-09T02:00:10.223Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","go","golang","migration","migrations","mysql","postgres","postgresql","schema","sql","sqlite"],"created_at":"2024-07-30T20:01:20.328Z","updated_at":"2025-09-09T20:18:20.819Z","avatar_url":"https://github.com/pressly.png","language":"Go","readme":"# goose\n\n\u003cimg align=\"right\" width=\"125\" src=\"assets/goose_logo.png\"\u003e\n\n[![Goose\nCI](https://github.com/pressly/goose/actions/workflows/ci.yaml/badge.svg)](https://github.com/pressly/goose/actions/workflows/ci.yaml)\n[![Go\nReference](https://pkg.go.dev/badge/github.com/pressly/goose/v3.svg)](https://pkg.go.dev/github.com/pressly/goose/v3)\n[![Go Report\nCard](https://goreportcard.com/badge/github.com/pressly/goose/v3)](https://goreportcard.com/report/github.com/pressly/goose/v3)\n\nGoose is a database migration tool. Both a CLI and a library.\n\nManage your **database schema** by creating incremental SQL changes or Go functions.\n\n#### Features\n\n- Works against multiple databases:\n  - Postgres, MySQL, SQLite, YDB, ClickHouse, MSSQL, and\n    more.\n- Supports Go migrations written as plain functions.\n- Supports [embedded](https://pkg.go.dev/embed/) migrations.\n- Out-of-order migrations.\n- Seeding data.\n- Environment variable substitution in SQL migrations.\n- ... and more.\n\n# Install\n\n```shell\ngo install github.com/pressly/goose/v3/cmd/goose@latest\n```\n\nThis will install the `goose` binary to your `$GOPATH/bin` directory.\n\nBinary too big? Build a lite version by excluding the drivers you don't need:\n\n```shell\ngo build -tags='no_postgres no_mysql no_sqlite3 no_ydb' -o goose ./cmd/goose\n\n# Available build tags:\n#   no_clickhouse  no_libsql   no_mssql    no_mysql\n#   no_postgres    no_sqlite3  no_vertica  no_ydb\n```\n\nFor macOS users `goose` is available as a [Homebrew\nFormulae](https://formulae.brew.sh/formula/goose#default):\n\n```shell\nbrew install goose\n```\n\nSee [installation documentation](https://pressly.github.io/goose/installation/) for more details.\n\n# Usage\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to show \u003ccode\u003egoose help\u003c/code\u003e output\u003c/summary\u003e\n\n```\nUsage: goose [OPTIONS] DRIVER DBSTRING COMMAND\n\nor\n\nSet environment key\nGOOSE_DRIVER=DRIVER\nGOOSE_DBSTRING=DBSTRING\nGOOSE_MIGRATION_DIR=MIGRATION_DIR\n\nUsage: goose [OPTIONS] COMMAND\n\nDrivers:\n    postgres\n    mysql\n    sqlite3\n    mssql\n    redshift\n    tidb\n    clickhouse\n    ydb\n    starrocks\n\nExamples:\n    goose sqlite3 ./foo.db status\n    goose sqlite3 ./foo.db create init sql\n    goose sqlite3 ./foo.db create add_some_column sql\n    goose sqlite3 ./foo.db create fetch_user_data go\n    goose sqlite3 ./foo.db up\n\n    goose postgres \"user=postgres dbname=postgres sslmode=disable\" status\n    goose mysql \"user:password@/dbname?parseTime=true\" status\n    goose redshift \"postgres://user:password@qwerty.us-east-1.redshift.amazonaws.com:5439/db\" status\n    goose tidb \"user:password@/dbname?parseTime=true\" status\n    goose mssql \"sqlserver://user:password@hostname:1433?database=master\" status\n    goose clickhouse \"tcp://127.0.0.1:9000\" status\n    goose ydb \"grpcs://localhost:2135/local?go_query_mode=scripting\u0026go_fake_tx=scripting\u0026go_query_bind=declare,numeric\" status\n    goose starrocks \"user:password@/dbname?parseTime=true\u0026interpolateParams=true\" status\n\n    GOOSE_DRIVER=sqlite3 GOOSE_DBSTRING=./foo.db goose status\n    GOOSE_DRIVER=sqlite3 GOOSE_DBSTRING=./foo.db goose create init sql\n    GOOSE_DRIVER=postgres GOOSE_DBSTRING=\"user=postgres dbname=postgres sslmode=disable\" goose status\n    GOOSE_DRIVER=mysql GOOSE_DBSTRING=\"user:password@/dbname\" goose status\n    GOOSE_DRIVER=redshift GOOSE_DBSTRING=\"postgres://user:password@qwerty.us-east-1.redshift.amazonaws.com:5439/db\" goose status\n    GOOSE_DRIVER=clickhouse GOOSE_DBSTRING=\"clickhouse://user:password@qwerty.clickhouse.cloud:9440/dbname?secure=true\u0026skip_verify=false\" goose status\n\nOptions:\n\n  -allow-missing\n        applies missing (out-of-order) migrations\n  -certfile string\n        file path to root CA's certificates in pem format (only support on mysql)\n  -dir string\n        directory with migration files (default \".\", can be set via the GOOSE_MIGRATION_DIR env variable).\n  -h    print help\n  -no-color\n        disable color output (NO_COLOR env variable supported)\n  -no-versioning\n        apply migration commands with no versioning, in file order, from directory pointed to\n  -s    use sequential numbering for new migrations\n  -ssl-cert string\n        file path to SSL certificates in pem format (only support on mysql)\n  -ssl-key string\n        file path to SSL key in pem format (only support on mysql)\n  -table string\n        migrations table name (default \"goose_db_version\")\n  -timeout duration\n        maximum allowed duration for queries to run; e.g., 1h13m\n  -v    enable verbose mode\n  -version\n        print version\n\nCommands:\n    up                   Migrate the DB to the most recent version available\n    up-by-one            Migrate the DB up by 1\n    up-to VERSION        Migrate the DB to a specific VERSION\n    down                 Roll back the version by 1\n    down-to VERSION      Roll back to a specific VERSION\n    redo                 Re-run the latest migration\n    reset                Roll back all migrations\n    status               Dump the migration status for the current DB\n    version              Print the current version of the database\n    create NAME [sql|go] Creates new migration file with the current timestamp\n    fix                  Apply sequential ordering to migrations\n    validate             Check migration files without running them\n```\n\n\u003c/details\u003e\n\nCommonly used commands:\n\n[create](#create)\u003cspan\u003e\u0026nbsp;•\u0026nbsp;\u003c/span\u003e [up](#up)\u003cspan\u003e\u0026nbsp;•\u0026nbsp;\u003c/span\u003e [up-to](#up-to)\u003cspan\u003e\u0026nbsp;•\u0026nbsp;\u003c/span\u003e [down](#down)\u003cspan\u003e\u0026nbsp;•\u0026nbsp;\u003c/span\u003e [down-to](#down-to)\u003cspan\u003e\u0026nbsp;•\u0026nbsp;\u003c/span\u003e [status](#status)\u003cspan\u003e\u0026nbsp;•\u0026nbsp;\u003c/span\u003e [version](#version)\n\n## create\n\nCreate a new SQL migration.\n\n    $ goose create add_some_column sql\n    $ Created new file: 20170506082420_add_some_column.sql\n\n    $ goose -s create add_some_column sql\n    $ Created new file: 00001_add_some_column.sql\n\nEdit the newly created file to define the behavior of your migration.\n\nYou can also create a Go migration, if you then invoke it with [your own goose\nbinary](#go-migrations):\n\n    $ goose create fetch_user_data go\n    $ Created new file: 20170506082421_fetch_user_data.go\n\n## up\n\nApply all available migrations.\n\n    $ goose up\n    $ OK    001_basics.sql\n    $ OK    002_next.sql\n    $ OK    003_and_again.go\n\n## up-to\n\nMigrate up to a specific version.\n\n    $ goose up-to 20170506082420\n    $ OK    20170506082420_create_table.sql\n\n## up-by-one\n\nMigrate up a single migration from the current version\n\n    $ goose up-by-one\n    $ OK    20170614145246_change_type.sql\n\n## down\n\nRoll back a single migration from the current version.\n\n    $ goose down\n    $ OK    003_and_again.go\n\n## down-to\n\nRoll back migrations to a specific version.\n\n    $ goose down-to 20170506082527\n    $ OK    20170506082527_alter_column.sql\n\nOr, roll back all migrations (careful!):\n\n    $ goose down-to 0\n\n## status\n\nPrint the status of all migrations:\n\n    $ goose status\n    $   Applied At                  Migration\n    $   =======================================\n    $   Sun Jan  6 11:25:03 2013 -- 001_basics.sql\n    $   Sun Jan  6 11:25:03 2013 -- 002_next.sql\n    $   Pending                  -- 003_and_again.go\n\nNote: for MySQL [parseTime flag](https://github.com/go-sql-driver/mysql#parsetime) must be enabled.\n\nNote: for MySQL\n[`multiStatements`](https://github.com/go-sql-driver/mysql?tab=readme-ov-file#multistatements) must\nbe enabled. This is required when writing multiple queries separated by ';' characters in a single\nsql file.\n\n## version\n\nPrint the current version of the database:\n\n    $ goose version\n    $ goose: version 002\n\n# Environment Variables\n\nIf you prefer to use environment variables, instead of passing the driver and database string as\narguments, you can set the following environment variables:\n\n**1. Via environment variables:**\n\n```shell\nexport GOOSE_DRIVER=DRIVER\nexport GOOSE_DBSTRING=DBSTRING\nexport GOOSE_MIGRATION_DIR=MIGRATION_DIR\nexport GOOSE_TABLE=TABLENAME\n```\n\n**2. Via `.env` files with corresponding variables. `.env` file example**:\n\n```env\nGOOSE_DRIVER=postgres\nGOOSE_DBSTRING=postgres://admin:admin@localhost:5432/admin_db\nGOOSE_MIGRATION_DIR=./migrations\nGOOSE_TABLE=custom.goose_migrations\n```\n\nLoading from `.env` files is enabled by default. To disable this feature, set the `-env=none` flag.\nIf you want to load from a specific file, set the `-env` flag to the file path.\n\nFor more details about environment variables, see the [official documentation on environment\nvariables](https://pressly.github.io/goose/documentation/environment-variables/).\n\n# Migrations\n\ngoose supports migrations written in SQL or in Go.\n\n## SQL Migrations\n\nA sample SQL migration looks like:\n\n```sql\n-- +goose Up\nCREATE TABLE post (\n    id int NOT NULL,\n    title text,\n    body text,\n    PRIMARY KEY(id)\n);\n\n-- +goose Down\nDROP TABLE post;\n```\n\nEach migration file must have exactly one `-- +goose Up` annotation. The `-- +goose Down` annotation\nis optional. If the file has both annotations, then the `-- +goose Up` annotation **must** come\nfirst.\n\nNotice the annotations in the comments. Any statements following `-- +goose Up` will be executed as\npart of a forward migration, and any statements following `-- +goose Down` will be executed as part\nof a rollback.\n\nBy default, all migrations are run within a transaction. Some statements like `CREATE DATABASE`,\nhowever, cannot be run within a transaction. You may optionally add `-- +goose NO TRANSACTION` to\nthe top of your migration file in order to skip transactions within that specific migration file.\nBoth Up and Down migrations within this file will be run without transactions.\n\nBy default, SQL statements are delimited by semicolons - in fact, query statements must end with a\nsemicolon to be properly recognized by goose.\n\nMore complex statements (PL/pgSQL) that have semicolons within them must be annotated with `--\n+goose StatementBegin` and `-- +goose StatementEnd` to be properly recognized. For example:\n\n```sql\n-- +goose Up\n-- +goose StatementBegin\nCREATE OR REPLACE FUNCTION histories_partition_creation( DATE, DATE )\nreturns void AS $$\nDECLARE\n  create_query text;\nBEGIN\n  FOR create_query IN SELECT\n      'CREATE TABLE IF NOT EXISTS histories_'\n      || TO_CHAR( d, 'YYYY_MM' )\n      || ' ( CHECK( created_at \u003e= timestamp '''\n      || TO_CHAR( d, 'YYYY-MM-DD 00:00:00' )\n      || ''' AND created_at \u003c timestamp '''\n      || TO_CHAR( d + INTERVAL '1 month', 'YYYY-MM-DD 00:00:00' )\n      || ''' ) ) inherits ( histories );'\n    FROM generate_series( $1, $2, '1 month' ) AS d\n  LOOP\n    EXECUTE create_query;\n  END LOOP;  -- LOOP END\nEND;         -- FUNCTION END\n$$\nlanguage plpgsql;\n-- +goose StatementEnd\n```\n\nGoose supports environment variable substitution in SQL migrations through annotations. To enable\nthis feature, use the `-- +goose ENVSUB ON` annotation before the queries where you want\nsubstitution applied. It stays active until the `-- +goose ENVSUB OFF` annotation is encountered.\nYou can use these annotations multiple times within a file.\n\nThis feature is disabled by default for backward compatibility with existing scripts.\n\nFor `PL/pgSQL` functions or other statements where substitution is not desired, wrap the annotations\nexplicitly around the relevant parts. For example, to exclude escaping the `**` characters:\n\n```sql\n-- +goose StatementBegin\nCREATE OR REPLACE FUNCTION test_func()\nRETURNS void AS $$\n-- +goose ENVSUB ON\nBEGIN\n\tRAISE NOTICE '${SOME_ENV_VAR}';\nEND;\n-- +goose ENVSUB OFF\n$$ LANGUAGE plpgsql;\n-- +goose StatementEnd\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eSupported expansions (click here to expand):\u003c/summary\u003e\n\n- `${VAR}` or $VAR - expands to the value of the environment variable `VAR`\n- `${VAR:-default}` - expands to the value of the environment variable `VAR`, or `default` if `VAR`\n  is unset or null\n- `${VAR-default}` - expands to the value of the environment variable `VAR`, or `default` if `VAR`\n  is unset\n- `${VAR?err_msg}` - expands to the value of the environment variable `VAR`, or prints `err_msg` and\n  error if `VAR` unset\n- ~~`${VAR:?err_msg}` - expands to the value of the environment variable `VAR`, or prints `err_msg`\n  and error if `VAR` unset or null.~~ **THIS IS NOT SUPPORTED**\n\nSee\n[mfridman/interpolate](https://github.com/mfridman/interpolate?tab=readme-ov-file#supported-expansions)\nfor more details on supported expansions.\n\n\u003c/details\u003e\n\n## Embedded sql migrations\n\nGo 1.16 introduced new feature: [compile-time embedding](https://pkg.go.dev/embed/) files into\nbinary and corresponding [filesystem abstraction](https://pkg.go.dev/io/fs/).\n\nThis feature can be used only for applying existing migrations. Modifying operations such as `fix`\nand `create` will continue to operate on OS filesystem even if using embedded files. This is\nexpected behaviour because `io/fs` interfaces allows read-only access.\n\nMake sure to configure the correct SQL dialect, see [dialect.go](./dialect.go) for supported SQL\ndialects.\n\nExample usage, assuming that SQL migrations are placed in the `migrations` directory:\n\n```go\npackage main\n\nimport (\n    \"database/sql\"\n    \"embed\"\n\n    \"github.com/pressly/goose/v3\"\n)\n\n//go:embed migrations/*.sql\nvar embedMigrations embed.FS\n\nfunc main() {\n    var db *sql.DB\n    // setup database\n\n    goose.SetBaseFS(embedMigrations)\n\n    if err := goose.SetDialect(\"postgres\"); err != nil {\n        panic(err)\n    }\n\n    if err := goose.Up(db, \"migrations\"); err != nil {\n        panic(err)\n    }\n\n    // run app\n}\n```\n\nNote that we pass `\"migrations\"` as directory argument in `Up` because embedding saves directory\nstructure.\n\n## Go Migrations\n\n1. Create your own goose binary, see [example](./examples/go-migrations)\n2. Import `github.com/pressly/goose`\n3. Register your migration functions\n4. Include your `migrations` package into Go build: in `main.go`, `import _ \"github.com/me/myapp/migrations\"`\n5. Run goose command, ie. `goose.Up(db *sql.DB, dir string)`\n\nA [sample Go migration 00002_users_add_email.go file](./examples/go-migrations/00002_rename_root.go)\nlooks like:\n\n```go\npackage migrations\n\nimport (\n\t\"database/sql\"\n\n\t\"github.com/pressly/goose/v3\"\n)\n\nfunc init() {\n\tgoose.AddMigration(Up, Down)\n}\n\nfunc Up(tx *sql.Tx) error {\n\t_, err := tx.Exec(\"UPDATE users SET username='admin' WHERE username='root';\")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc Down(tx *sql.Tx) error {\n\t_, err := tx.Exec(\"UPDATE users SET username='root' WHERE username='admin';\")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n```\n\nNote that Go migration files must begin with a numeric value, followed by an underscore, and must\nnot end with `*_test.go`.\n\n# Hybrid Versioning\n\nPlease, read the [versioning\nproblem](https://github.com/pressly/goose/issues/63#issuecomment-428681694) first.\n\nBy default, if you attempt to apply missing (out-of-order) migrations `goose` will raise an error.\nHowever, If you want to apply these missing migrations pass goose the `-allow-missing` flag, or if\nusing as a library supply the functional option `goose.WithAllowMissing()` to Up, UpTo or UpByOne.\n\nHowever, we strongly recommend adopting a hybrid versioning approach, using both timestamps and\nsequential numbers. Migrations created during the development process are timestamped and sequential\nversions are ran on production. We believe this method will prevent the problem of conflicting\nversions when writing software in a team environment.\n\nTo help you adopt this approach, `create` will use the current timestamp as the migration version.\nWhen you're ready to deploy your migrations in a production environment, we also provide a helpful\n`fix` command to convert your migrations into sequential order, while preserving the timestamp\nordering. We recommend running `fix` in the CI pipeline, and only when the migrations are ready for\nproduction.\n\n## Credit\n\nThe gopher mascot was designed by [Renée French](https://reneefrench.blogspot.com/) / [CC\n3.0.](https://creativecommons.org/licenses/by/3.0/) For more info check out the [Go\nBlog](https://go.dev/blog/gopher). Adapted by Ellen.\n\n## License\n\nLicensed under [MIT License](./LICENSE)\n","funding_links":[],"categories":["数据库","开源类库","Database","Go","Golang Packages","Open source library","Generators","Uncategorized","sqlite","数据库  `go语言实现的数据库`","Repositories","Data Integration Frameworks","Programming"],"sub_categories":["标准 CLI","数据库","Database Schema Migration","Database","数据库模式迁移","Uncategorized","Advanced Console UIs","Go"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpressly%2Fgoose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpressly%2Fgoose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpressly%2Fgoose/lists"}