{"id":31006140,"url":"https://github.com/akito0107/xmigrate","last_synced_at":"2025-09-13T02:07:55.399Z","repository":{"id":84430940,"uuid":"186819220","full_name":"akito0107/xmigrate","owner":"akito0107","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-24T06:58:51.000Z","size":67,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-24T13:53:08.797Z","etag":null,"topics":["go","migration-tool","postgresql"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akito0107.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-15T12:12:39.000Z","updated_at":"2025-08-24T06:58:51.000Z","dependencies_parsed_at":"2023-03-12T22:58:24.585Z","dependency_job_id":null,"html_url":"https://github.com/akito0107/xmigrate","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/akito0107/xmigrate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akito0107%2Fxmigrate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akito0107%2Fxmigrate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akito0107%2Fxmigrate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akito0107%2Fxmigrate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akito0107","download_url":"https://codeload.github.com/akito0107/xmigrate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akito0107%2Fxmigrate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274907841,"owners_count":25371822,"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-13T02:00:10.085Z","response_time":70,"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":["go","migration-tool","postgresql"],"created_at":"2025-09-13T02:05:32.695Z","updated_at":"2025-09-13T02:07:55.387Z","avatar_url":"https://github.com/akito0107.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xmigrate/pgmigrate\n\nSchema first DB migration tool for PostgreSQL.\n\n[![Build Status](https://dev.azure.com/akito01070362/xmigrate/_apis/build/status/akito0107.xmigrate?branchName=master)](https://dev.azure.com/akito01070362/xmigrate/_build/latest?definitionId=3\u0026branchName=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/akito0107/xmigrate)](https://goreportcard.com/report/github.com/akito0107/xmigrate)\n[![codecov](https://codecov.io/gh/akito0107/xmigrate/branch/master/graph/badge.svg)](https://codecov.io/gh/akito0107/xmigrate)\n\n## Getting Started\n\n### Prerequisites\n- Go 1.12+\n\n### Installing\n```\n$ go get -u github.com/akito0107/xmigrate/cmd/pgmigrate\n```\n\n### How To Use\n1. Prepare Database.\n\n```\n# psql -U postgres\npsql (9.6.10)\n\npostgres=# create database xmigrate_tutorial;\nCREATE DATABASE\n```\n\n2. Create `shcema` file.\n\n```sql\nCREATE TABLE ACCOUNT (\n    id serial primary key,\n    email varchar unique not null,\n    name varchar,\n    created_at timestamp with time zone default current_timestamp\n);\n```\n\n3. Call sync command with `-f` option.\n\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/xmigrate_tutorial\ndry-run mode (with --apply flag will be exec below queries)\napplying: CREATE TABLE ACCOUNT (id serial PRIMARY KEY, email character varying UNIQUE NOT NULL, name character varying, created_at timestamp with timezone DEFAULT current_timestamp)\n```\n\n4. Recall sync with `--apply` option.\n```\n$ pgmigrate -f schema.sql --apply postgres://[USER_NAME]:[PASSWORD]@localhost:5432/xmigrate_tutorial\napplying: CREATE TABLE ACCOUNT (id serial PRIMARY KEY, email character varying UNIQUE NOT NULL, name character varying, created_at timestamp with time zone DEFAULT current_timestamp)\n```\n\n5. Check DB Stats\n```\n# psql -U postgres --dbname xmigrate_tutorial\npsql (9.6.10)\nType \"help\" for help.\n\nxmigrate_tutorial=# \\d\n               List of relations\n Schema |      Name      |   Type   |  Owner\n--------+----------------+----------+----------\n public | account        | table    | postgres\n public | account_id_seq | sequence | postgres\n(2 rows)\n\nxmigrate_tutorial=# \\d account\n                                    Table \"public.account\"\n   Column   |           Type           |                      Modifiers\n\n------------+--------------------------+------------------------------------------------------\n id         | integer                  | not null default nextval('account_id_seq'::regclass)\n email      | character varying        | not null\n name       | character varying        |\n created_at | timestamp with time zone | default now()\nIndexes:\n    \"account_pkey\" PRIMARY KEY, btree (id)\n    \"account_email_key\" UNIQUE CONSTRAINT, btree (email)\n```\n\n6. Modify Schema\n```diff\nCREATE TABLE ACCOUNT (\n     id serial primary key,\n     email varchar unique not null,\n     name varchar,\n+    address varchar not null,\n     created_at timestamp with time zone default current_timestamp\n );\n```\n\n7. Preview \u0026 Apply\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: ALTER TABLE account ADD COLUMN address character varying NOT NULL\n\n$ pgmigrate -f schema.sql --apply postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\napplying: ALTER TABLE account ADD COLUMN address character varying NOT NULL\n```\n\n8. Check DB stats\n```\nxmigrate_tutorial=# \\d account\n                                    Table \"public.account\"\n   Column   |           Type           |                      Modifiers\n------------+--------------------------+------------------------------------------------------\n id         | integer                  | not null default nextval('account_id_seq'::regclass)\n email      | character varying        | not null\n name       | character varying        |\n created_at | timestamp with time zone | default now()\n address    | character varying        | not null\nIndexes:\n    \"account_pkey\" PRIMARY KEY, btree (id)\n    \"account_email_key\" UNIQUE CONSTRAINT, btree (email)\n```\n\n## Supported Operation\n### Create Table\n\ngiven:\n```diff\n+CREATE TABLE ITEM (\n+    ID serial primary key,\n+    NAME varchar not null,\n+    PRICE int not null\n+);\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: CREATE TABLE ITEM (ID serial PRIMARY KEY, NAME character varying NOT NULL, PRICE int NOT NULL)\n```\n\n### Drop Table\n\ngiven:\n```diff\n-CREATE TABLE ITEM (\n-    ID serial primary key,\n-    NAME varchar not null,\n-    PRICE int not null\n-);\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: DROP TABLE IF EXISTS item\n```\n\n### Add Column\n\ngiven:\n```diff\nCREATE TABLE ACCOUNT (\n     EMAIL varchar unique not null,\n     NAME varchar,\n     ADDRESS varchar not null,\n+    ADDRESS2 varchar,\n     CREATED_AT timestamp with time zone default current_timestamp\n );\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: ALTER TABLE account ADD COLUMN ADDRESS2 character varying\n```\n\n### Drop Column\n\ngiven:\n```diff\nCREATE TABLE ACCOUNT (\n     EMAIL varchar unique not null,\n     NAME varchar,\n     ADDRESS varchar not null,\n-    ADDRESS2 varchar,\n     CREATED_AT timestamp with time zone default current_timestamp\n );\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: ALTER TABLE account DROP COLUMN address2\n```\n\n### Modify Column\n#### Change Data Type\n    \ngiven:\n```diff\nCREATE TABLE ACCOUNT (\n     ID serial primary key,\n     EMAIL varchar unique not null,\n     NAME varchar,\n-    ADDRESS varchar not null,\n+    ADDRESS text not null,\n     CREATED_AT timestamp with time zone default current_timestamp\n );\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: ALTER TABLE ACCOUNT ALTER COLUMN ADDRESS TYPE text\n```\n\n#### Add Column Constraint (NOT NULL)\n\ngiven:\n```diff\n CREATE TABLE ACCOUNT (\n     ID serial primary key,\n     EMAIL varchar unique not null,\n-    NAME varchar,\n+    NAME varchar not null,\n     ADDRESS text not null,\n     CREATED_AT timestamp with time zone default current_timestamp\n );\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: ALTER TABLE ACCOUNT ALTER COLUMN NAME SET NOT NULL\n```\n\n#### Remove Column Constraint (NOT NULL)\n\ngiven:\n```diff\n CREATE TABLE ACCOUNT (\n     ID serial primary key,\n     EMAIL varchar unique not null,\n-    NAME varchar not null,\n+    NAME varchar,\n     ADDRESS text not null,\n     CREATED_AT timestamp with time zone default current_timestamp\n );\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: ALTER TABLE ACCOUNT ALTER COLUMN NAME DROP NOT NULL\n```\n\n#### Add Table Constraint\n\ngiven:\n```diff\nCREATE TABLE ACCOUNT (\n     EMAIL varchar unique not null,\n     NAME varchar not null,\n     ADDRESS text not null,\n     CREATED_AT timestamp with time zone default current_timestamp,\n+    CONSTRAINT unique_name_address UNIQUE (NAME, ADDRESS)\n );\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: ALTER TABLE ACCOUNT ADD CONSTRAINT unique_name_address UNIQUE(NAME, ADDRESS)\n```\n\nCAUTION ONLY SUPPORTS *NAMED* CONSTRAINT. ex) the following case is not handled correctly.\n\n```diff\nCREATE TABLE ACCOUNT (\n     EMAIL varchar unique not null,\n     NAME varchar not null,\n     ADDRESS text not null,\n     CREATED_AT timestamp with time zone default current_timestamp,\n+    UNIQUE (NAME, ADDRESS)\n );\n```\n\n#### Remove Table Constraint\n\ngiven:\n```diff\nCREATE TABLE ACCOUNT (\n     EMAIL varchar unique not null,\n     NAME varchar not null,\n     ADDRESS text not null,\n     CREATED_AT timestamp with time zone default current_timestamp\n-    CONSTRAINT unique_name_address UNIQUE (NAME, ADDRESS)\n );\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: ALTER TABLE ACCOUNT DROP CONSTRAINT unique_name_address\n```\n\n### Create Index\n\ngiven:\n```diff\n+ CREATE INDEX name_idx ON account (name);\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\napplying: CREATE INDEX cat_name_idx ON item (category_id, name)\n```\n\n### Drop Index\n\ngiven:\n```diff\n- CREATE INDEX name_idx ON account (name);\n```\n\nthen:\n```\n$ pgmigrate -f schema.sql postgres://[USER_NAME]:[PASSWORD]@localhost:5432/\ndry-run mode (with --apply flag will be exec below queries)\nDROP INDEX name_idx\n```\n\n### options\n```\nNAME:\n   pgmigrate - postgres db migration utility\n\nUSAGE:\n   pgmigrate [GLOBAL OPTIONS] [db url]\n\nVERSION:\n   0.0.0\n\nCOMMANDS:\n     help, h  Shows a list of commands or help for one command\n\nGLOBAL OPTIONS:\n   --schemapath value, -f value  schema sql path (default: \"schema.sql\")\n   --apply, -a                   apply migration\n   --help, -h                    show help\n   --version, -v                 print the version\n```\n\n## License\nThis project is licensed under the Apache License 2.0 License - see the [LICENSE](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakito0107%2Fxmigrate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakito0107%2Fxmigrate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakito0107%2Fxmigrate/lists"}