{"id":14070469,"url":"https://github.com/andywer/plow","last_synced_at":"2025-04-15T10:51:17.873Z","repository":{"id":38030217,"uuid":"231889624","full_name":"andywer/plow","owner":"andywer","description":"👨‍🌾 Postgres migrations and seeding made easy","archived":false,"fork":false,"pushed_at":"2022-06-23T02:08:31.000Z","size":173,"stargazers_count":14,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T19:13:12.096Z","etag":null,"topics":["database","docker","migration","migrations","postgres","postgres-migrations","postgresql","seed","seeding"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/repository/docker/andywer/plow","language":"TypeScript","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/andywer.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}},"created_at":"2020-01-05T08:36:01.000Z","updated_at":"2022-12-20T23:29:35.000Z","dependencies_parsed_at":"2022-08-20T18:10:25.303Z","dependency_job_id":null,"html_url":"https://github.com/andywer/plow","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andywer%2Fplow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andywer%2Fplow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andywer%2Fplow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andywer%2Fplow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andywer","download_url":"https://codeload.github.com/andywer/plow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249057596,"owners_count":21205904,"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","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","docker","migration","migrations","postgres","postgres-migrations","postgresql","seed","seeding"],"created_at":"2024-08-13T07:07:47.233Z","updated_at":"2025-04-15T10:51:17.841Z","avatar_url":"https://github.com/andywer.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003ePlow :man_farmer:\u003c/h1\u003e\n\u003cp align=\"center\"\u003ePostgres migrations \u0026 seeding made easy\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://npmjs.com/package/@andywer/plow\"\u003e\u003cimg src=\"https://badgen.net/npm/v/@andywer/plow\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://hub.docker.com/repository/docker/andywer/plow\"\u003e\u003cimg src=\"https://badgen.net/docker/size/andywer/plow/latest?icon=docker\u0026label=image+size\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nPlow is a no-non-sense tool to quickly and easily apply database migrations and seed PostgresQL databases.\n\nThe migrations are managed using [`postgres-migrations`](https://www.npmjs.com/package/postgres-migrations).\n\n## Installation\n\n```\n$ npm install @andywer/plow\n```\n\n## Usage - Command line tool\n\n```\nUsage\n  $ plow migrate ./migrations/*.sql\n  $ plow seed ./seeds/*.sql\n\nGeneral options\n  --help                Print this usage help\n  --verbose             Enable more detailed logging\n  --version             Print the installed plow version\n\nConnection options\n  --database \u003cname\u003e     Name of the database\n  --host \u003chost\u003e         Database host, defaults to \"localhost\"\n  --port \u003cport\u003e         Port the database listens on, defaults to 5432\n  --user \u003cname\u003e         User name to authenticate as\n  --password \u003cpassword\u003e Password to use for authentication\n\nEnvironment variables\n  You can also configure the connection using these environment variables.\n\n  PGDATABASE, PGHOST, PGPASSWORD, PGPORT, PGUSER\n```\n\nUse `npx` to run a locally installed `plow` like this:\n\n```\nnpx plow migrate ./migrations\n```\n\n## Usage - Docker\n\nUse the `andywer/plow` docker image. You can add it to your `docker-compose.yml` file like this:\n\n```\nversion: \"3.7\"\nservices:\n  postgres:\n    image: postgres:12-alpine\n    environment:\n      POSTGRES_PASSWORD: $PGPASSWORD\n    ports:\n      - 5432:5432\n  db_seeder:\n    image: andywer/plow:0.0.0\n    depends_on:\n      - postgres\n    env_file: ./.env\n    environment:\n      PGHOST: postgres\n    restart: \"no\"\n    volumes:\n      - ./migrations:/migrations\n      - ./seeds:/seeds\n```\n\nNow every time you run `docker-compose up` your database will automatically have all migrations and seeds applied! :rocket:\n\nNote that we assume you have a local `migrations` and a `seeds` directory that we can mount into the container and that you have a `.env` file next to your docker-compose file:\n\n```\nPGDATABASE=postgres\nPGHOST=localhost\nPGUSER=postgres\nPGPASSWORD=postgres\n```\n\nThe output of `docker-compose up` will look something like this:\n\n```\n$ docker-compose up\ntwitter-daily_postgres_1 is up-to-date\nCreating twitter-daily_db_seeder_1 ... done\nAttaching to twitter-daily_postgres_1, twitter-daily_db_seeder_1\n...\npostgres_1   | 2020-01-05 04:50:04.266 UTC [1] LOG:  database system is ready to accept connections\ndb_seeder_1  | Database migration done.\ndb_seeder_1  | Migrations run:\ndb_seeder_1  |   - create-migrations-table\ndb_seeder_1  |   - v0.1.0-initial\ndb_seeder_1  | Database seeded.\ndb_seeder_1  | Applied seeds:\ndb_seeder_1  |   (None)\ntwitter-daily_db_seeder_1 exited with code 0\n```\n\n## Migration files\n\nMigration files can either be plain SQL files or JavaScript files. There are only up migrations, no down migrations – this is a design decision. Read more about it [here](https://www.npmjs.com/package/postgres-migrations).\n\nA good scheme to name your migration files is:\n\n```\n\u003cserial\u003e-\u003cversion\u003e-\u003cdescription\u003e.sql\n```\n\nSo the very first migration file would be called `01-v0.1.0-initial.sql` or similar.\n\n## Seed files\n\nSeed files are supposed to be plain SQL files.\n\n```\n/* example.seed.sql */\n\nINSERT INTO users\n  (name, email, email_confirmed)\nVALUES\n  ('Alice', 'alice@example.org', TRUE);\n```\n\n## FAQs\n\n### Error: Migration failed. Reason: Hashes don't match for migrations\n\nPlow uses `postgres-migrations` which sets up a migration table and stores a hash for every migration run. You will see this error if you change a migration file (during development, I hope) that you already applied and run plow again.\n\n**Only during development:** Assuming that you have no valuable data in your local development database, it's easy to just whipe the whole database and restart the containers to re-run the migrations to start off fresh again. If you have a local docker-compose setup with a database container without a mount, then just run `docker-compose rm --stop postgres \u0026\u0026 docker-compose up` to re-initialize the whole database.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandywer%2Fplow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandywer%2Fplow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandywer%2Fplow/lists"}