{"id":39272129,"url":"https://github.com/nettrash/pgc","last_synced_at":"2026-04-21T08:01:09.076Z","repository":{"id":323038889,"uuid":"967471044","full_name":"nettrash/pgc","owner":"nettrash","description":"PostgreSQL Database Comparer","archived":false,"fork":false,"pushed_at":"2026-04-16T09:17:07.000Z","size":1356,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-04-16T10:30:32.543Z","etag":null,"topics":["comparison","database","postgresql","rust"],"latest_commit_sha":null,"homepage":"https://nettrash.me","language":"Rust","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/nettrash.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"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":"2025-04-16T14:00:39.000Z","updated_at":"2026-04-16T10:07:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"e8709797-ab66-446e-a39a-d0cde7c5ed5c","html_url":"https://github.com/nettrash/pgc","commit_stats":null,"previous_names":["nettrash/pgc"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/nettrash/pgc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nettrash%2Fpgc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nettrash%2Fpgc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nettrash%2Fpgc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nettrash%2Fpgc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nettrash","download_url":"https://codeload.github.com/nettrash/pgc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nettrash%2Fpgc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32082780,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T06:27:27.065Z","status":"ssl_error","status_checked_at":"2026-04-21T06:27:21.250Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["comparison","database","postgresql","rust"],"created_at":"2026-01-18T00:48:04.106Z","updated_at":"2026-04-21T08:01:09.071Z","avatar_url":"https://github.com/nettrash.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostgreSQL Database Comparer\n\n![rust workflow](https://github.com/nettrash/pgc/actions/workflows/rust.yml/badge.svg)\n\n## Story\n\nWe're faced with vital need to have a proper working free tool for comparing two PostgreSQL databases and preparing the delta as SQL script.\n\nWe have multiple PostgreSQL database repositories and need to have a properly working deployment pipelines for our databases.\n\n## Glossary\n\n- `FROM` - this database we will use a target database, we want to apply final patch here.\n- `TO` - this database we will use as an etalon schema, and prepare delta script that can be applied on FROM database to make schema equals to schema of database `TO`.\n\n## How to build\n\n```bash\ncargo fmt --all -- --check\ncargo clippy --all-targets --all-features\ncargo test  \ncargo build\n```\n\n## How to run\n\n```bash\ncargo run [options]\npgc [options]\n```\n\nWe have two opportunities to run:\n\n- use configuration file;\n- use command line arguments.\n\nConfiguration file can help us to put different functions in a chain.\nCommand line arguments can be used to execute just one function in one time.\n\n## Command line arguments\n\n`--command {dump|compare|clear}` - the command name, dump - to create a dump file, compare - to compare two dumps, clear - to generate a script that drops all objects found in the database.\n\n`--server {server name}` - to specify `server name` for a command, without it tool will use localhost as a host for command.\n\n`--port {port number}` - to specify `port number` for a command, without it tool will use 5432 as a host for command.\n\n`--user {user name}` - to specify `user name` for a command, without it tool will use information from pgpass file.\n\n`--password {user password}` - to specify `user password` for a command, without it tool will use information from pgpass file.\n\n`--database {databasename}` - to specify `database name` for the command, without it tool will use `postgres` as a database name.\n\n`--scheme {schemaname}` - to specify concrete scheme for the command, without it all schemas will be used for command.\n\n`--output {filename}` - to specify output file name for the command, without it the tool will use `data.out` as a file name for output file.\n\n`--from {filename}` - to specify dump file of the `FROM` databadse for the comparer, default value for this property `dump.from`.\n\n`--to {filename}` - to specify dump file of the `TO` databadse for the comparer, default value for this property is `dump.to`.\n\n`--config {filename}` - this argument avoid usage of any other arguments, and tell comparer to use command chain from this file. Default: `pgc.conf`.\n\n`--use_ssl` - specify this argument to use SSL for PostgreSQL connection.\n\n`--use-drop` - specify this argument if you want to use DROPs in output script, otherwise no DROPs will be used.\n\n`--use-single-transaction` - use this flag to wrap resulting diff file within explicit `begin;` and `commit;` statements (i.e. single transaction).\n\n`--use-comments {true|false}` - set to `false` to strip SQL comments from the generated script; set to `true` (default) to include comments.\n\n`--grants-mode {ignore|addonly|full}` - controls how grants (privileges) are handled during comparison. `ignore` (default) skips grants entirely; `addonly` adds grants that exist in TO but not in FROM; `full` makes grants identical by adding missing and revoking extra.\n\n`--max-connections {number}` - maximum number of connections in the PostgreSQL connection pool. Default: `16`. Used by all concurrent introspection queries; table metadata is pulled schema-wide in one query per resource kind (columns, indexes, constraints, triggers, policies, partition info, definitions) so connection count mostly matters for the sibling queries (extensions, sequences, routines, views, etc.) running in parallel.\n\n`--use-cascade` - add `CASCADE` to every `DROP` statement in the clear script. **Warning:** `CASCADE` can silently drop dependent objects that live outside the selected schema(s) (e.g., foreign keys or views in other schemas referencing the dropped objects). Use only when you are certain no cross-schema dependencies should survive. Without this flag the generated drops rely on the explicit dependency ordering and will fail cleanly if unresolved dependencies exist.\n\n## Functionality\n\n### Create database schema dump\n\n```bash\npgc  --command dump --server {host} --database {database} --scheme {scheme} --output {file}\n```\n\nAs a result if this command we will have a dump file with all needed information to compile delta between two databases. This file should be used for the `FROM` or `TO` sides in `compare` command.\n\n### Create delta script between two dumps\n\n```bash\npgc --command compare --from {from_dump} --to {to_dump} --output {file} --use-drop\n```\n\nThis command comparing two dumps and produce SQL script for the `FROM` database to be equal to `TO` database after applying it.\nIf we add `--use-drop` argument comparer will add drop scripts for all items that non exists in target database, otherwise drop scripts will be ignored.  \nBy default, comparer ignore drops.\n\n### Generate a clear (drop-all) script for a database\n\n```bash\npgc --command clear --server {host} --database {database} --scheme {scheme} --output {file} --use-single-transaction --use-comments\n```\n\nThis command connects to the specified database, discovers all objects in the given schema(s) and produces a SQL script that drops every found object in dependency-safe order:\n\n1. Views (topologically sorted by `table_relation`; tie-break: materialized before regular, then alphabetical)\n2. Foreign key constraints\n3. Tables\n4. Routines (functions, procedures, aggregates)\n5. Sequences\n6. Types (enums, composites, domains)\n7. Extensions\n8. Schemas\n\nThe resulting script can be applied on another database that shares the same schema to fully remove all objects originating from it.\n\nOptional flags:\n- `--use-single-transaction` wraps the script in `BEGIN` / `COMMIT`.\n- `--use-comments` (default `true`) adds explanatory comments before each drop statement.\n- `--use-cascade` appends `CASCADE` to every `DROP` statement so that dependent objects outside the inspected schema(s) are removed automatically. **Use with caution** — this can drop objects you did not intend to remove (see `--use-cascade` description above).\n\n## Configuration file\n\nThe configuration file is pretty simple key-value configuration file. All rows starts from `#` will be interpreted as a comments. Also will be ignored all empty or whitespace rows.\n\nAll configuration file should based on the following one:\n\n```conf\n# \n# PostgreSQL Comparer Configuration\n# \n\n# FROM\nFROM_HOST=localhost\nFROM_DATABASE=service\nFROM_SCHEME=service\nFROM_SSL=true\nFROM_DUMP=from.dump\n\n# TO\nTO_HOST=localhost\nTO_DATABASE=service\nTO_SCHEME=service\nTO_SSL=false\nTO_DUMP=to.dump\n\n# OUTPUT\nOUTPUT=delta.sql\n\n# ADDITIONAL PROPERTIES\nUSE_DROP=true\nUSE_SINGLE_TRANSACTION=true\nUSE_COMMENTS=false\nGRANTS_MODE=ignore\nMAX_CONNECTIONS=16\n```\n\n## Choosing `MAX_CONNECTIONS`\n\n`MAX_CONNECTIONS` caps the connection pool the tool opens per dump. Independent introspection queries (extensions, sequences, routines, views, types, tables, etc.) are fired concurrently via `tokio::try_join!`, and the table-level data (columns, indexes, constraints, triggers, policies, partition info, definitions) is pulled with **schema-wide** queries — one query per sub-resource, independent of table count. So the connection count mostly bounds how many of the ~18 concurrent sibling queries run without queueing.\n\n### Key constraints\n\n- **Server budget** — never exceed half of the server's `max_connections` (check with `SHOW max_connections;`). The PostgreSQL default is 100.\n- **Two pools** — when dumping both `FROM` and `TO` against the same server the combined usage is `2 × MAX_CONNECTIONS`; halve your budget per pool.\n- **Memory overhead** — each PostgreSQL connection costs roughly 5–10 MB of RAM on the server.\n- **Diminishing returns** — beyond ~24 connections there is nothing left to parallelize; the dump runs at most ~18 queries concurrently.\n\n### Recommended values\n\n| Schema size                 | Suggested `MAX_CONNECTIONS` |\n|-----------------------------|-----------------------------|\n| Local or low-latency server | 16 (default)                |\n| High-latency / remote       | 20 – 24                     |\n| Extremely small schema      | 8 – 12 (still fine)         |\n\nThe default of 16 is comfortable for most workloads. Raising it above ~24 rarely helps: the tool only has a small fixed set of sibling query batches to run.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnettrash%2Fpgc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnettrash%2Fpgc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnettrash%2Fpgc/lists"}