{"id":37220196,"url":"https://github.com/bolajiwahab/pgrubic","last_synced_at":"2026-02-18T00:12:38.590Z","repository":{"id":270043992,"uuid":"805137838","full_name":"bolajiwahab/pgrubic","owner":"bolajiwahab","description":"PostgreSQL linter and formatter for schema migrations and design best practices.","archived":false,"fork":false,"pushed_at":"2025-12-20T08:27:57.000Z","size":7269,"stargazers_count":13,"open_issues_count":4,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-22T14:48:20.277Z","etag":null,"topics":["code-quality","continuous-integration","formatter","formatting","linter","postgres","postgresql","pre-commit-hook","river-styling","sql","static-analysis","static-code-analysis","style-guide"],"latest_commit_sha":null,"homepage":"https://bolajiwahab.github.io/pgrubic/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bolajiwahab.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-05-24T00:44:32.000Z","updated_at":"2025-12-20T08:26:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"3fb76379-c77a-42ff-ae42-b9357c6ace71","html_url":"https://github.com/bolajiwahab/pgrubic","commit_stats":null,"previous_names":["bolajiwahab/pgrubic"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/bolajiwahab/pgrubic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bolajiwahab%2Fpgrubic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bolajiwahab%2Fpgrubic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bolajiwahab%2Fpgrubic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bolajiwahab%2Fpgrubic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bolajiwahab","download_url":"https://codeload.github.com/bolajiwahab/pgrubic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bolajiwahab%2Fpgrubic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28441031,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:55:22.719Z","status":"ssl_error","status_checked_at":"2026-01-15T00:55:20.945Z","response_time":107,"last_error":"SSL_read: 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":["code-quality","continuous-integration","formatter","formatting","linter","postgres","postgresql","pre-commit-hook","river-styling","sql","static-analysis","static-code-analysis","style-guide"],"created_at":"2026-01-15T01:21:58.648Z","updated_at":"2026-02-18T00:12:38.582Z","avatar_url":"https://github.com/bolajiwahab.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pgrubic\n\n[![pgrubic](https://img.shields.io/badge/pgrubic-purple.svg)](https://github.com/bolajiwahab/pgrubic/)\n[![PyPI - Version](https://img.shields.io/pypi/v/pgrubic)](https://pypi.org/project/pgrubic/)\n[![PyPI - Status](https://img.shields.io/pypi/status/pgrubic)](https://pypi.org/project/pgrubic/)\n[![PyPI - License](https://img.shields.io/pypi/l/pgrubic)](https://github.com/bolajiwahab/pgrubic/blob/main/LICENSE)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pgrubic)](https://pypi.org/project/pgrubic/)\n[![CI](https://github.com/bolajiwahab/pgrubic/actions/workflows/ci.yml/badge.svg)](https://github.com/bolajiwahab/pgrubic/actions/workflows/ci.yml)\n[![Coverage badge](https://github.com/bolajiwahab/pgrubic/raw/python-coverage-comment-action-data/badge.svg)](https://github.com/bolajiwahab/pgrubic/tree/python-coverage-comment-action-data)\n[![DOC](https://github.com/bolajiwahab/pgrubic/actions/workflows/doc.yml/badge.svg)](https://github.com/bolajiwahab/pgrubic/actions/workflows/doc.yml)\n[![release](https://github.com/bolajiwahab/pgrubic/actions/workflows/release.yml/badge.svg)](https://github.com/bolajiwahab/pgrubic/actions/workflows/release.yml)\n[![PyPI Total Downloads](https://img.shields.io/pepy/dt/pgrubic)](https://pepy.tech/projects/pgrubic)\n[![CodeQL](https://github.com/bolajiwahab/pgrubic/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/bolajiwahab/pgrubic/actions/workflows/github-code-scanning/codeql)\n[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v0.json)](https://github.com/charliermarsh/ruff)\n[![types - mypy](https://img.shields.io/badge/types-mypy-blue.svg)](https://github.com/python/mypy)\n[![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)\n[![Socket Badge](https://socket.dev/api/badge/pypi/package/pgrubic?artifact_id=tar-gz)](https://socket.dev/pypi/package/pgrubic/overview/)\n[![Dependency Review](https://img.shields.io/badge/Dependency%20Review-enabled-deepgreen)](https://github.com/bolajiwahab/pgrubic/actions/workflows/dependency-review.yml)\n\npgrubic is a PostgreSQL linter and formatter for schema migrations and design best practices.\n\n## Features\n\n- Over 100+ rules\n- Automatic violation correction (e.g., automatically add `concurrently` to index create statements)\n- River style code formatting for DML statements\n- Almost identical stying with **pg_dump** for DDL statements\n- Python 3.12+ compatibility\n- Automatic caching to avoid reformatting unchanged files\n- Violations suppression, statement level, and file level\n\n## Getting Started\n\nFor more, see the [documentation](https://bolajiwahab.github.io/pgrubic/).\n\n## Installation\n\n```bash\npip install pgrubic\n```\n\n**\u003cspan style=\"color:red\"\u003epgrubic is only supported on Python 3.12 or higher\u003c/span\u003e**.\n\n## Usage\n\nFor linting, try any of the following:\n\n```bash\npgrubic lint                         # Lint SQL files in the current directory (and any subdirectories)\npgrubic lint .                       # Lint SQL files in the current directory (and any subdirectories)\npgrubic lint directory               # Lint SQL files in *directory* (and any subdirectories)\npgrubic lint directory/*.sql         # Lint SQL files in *directory*\npgrubic lint directory/file.sql      # Lint `file.sql` in *directory*\npgrubic lint file.sql                # Lint `file.sql`\npgrubic lint directory/*.sql --fix   # Lint SQL files in *directory* and fix violations automatically\npgrubic lint file.sql --fix          # Lint `file.sql` and fix fixable violations automatically\n```\n\nSample output from linting:\n\n```bash\npgrubic lint *.sql\n\nfile.sql:1:38: TP017: Boolean field should be not be nullable\n\n1 | ALTER TABLE public.example ADD COLUMN foo boolean DEFAULT false;\n```\n\n```bash\npgrubic file.sql\n\ntest.sql:1:38: TP017: Boolean field should be not be nullable\n\n1 | ALTER TABLE public.example ADD COLUMN foo boolean DEFAULT false;\n```\n\nFor formatting, try any of the following:\n\n```bash\npgrubic format                         # Format SQL files in the current directory (and any subdirectories)\npgrubic format .                       # Format SQL files in the current directory (and any subdirectories)\npgrubic format directory               # Format SQL files in *directory* (and any subdirectories)\npgrubic format directory/*.sql         # Format SQL files in *directory*\npgrubic format directory/file.sql      # Format `file.sql` in *directory*\npgrubic format file.sql                # Format `file.sql`\npgrubic format directory/*.sql --check # Check if SQL files would have been modified, returning a non-zero exit code\npgrubic format file.sql --diff         # Report if `file.sql` would have been modified, returning a non-zero exit code as well the difference between `file.sql` and how the formatted file would look like\n```\n\npgrubic can also be used as a pre-commit hook:\n\n```\n- repo: https://github.com/bolajiwahab/pgrubic\n  rev: 0.10.1\n  hooks:\n    - id: pgrubic-lint\n    - id: pgrubic-format\n```\n\n## Configuration\n\npgrubic can be configured via the [`pgrubic.toml`] file in either the current directory, up to the root directory or the path set by the `PGRUBIC_CONFIG_PATH` environment variable.\n\nThe following configuration options are available in the [`pgrubic.toml`] with the following defaults:\n\n```toml\n# Path to the cache directory\ncache-dir = \".pgrubic_cache\"\n\n# Include all files by default\ninclude = []\n\n# Exclude no files by default\nexclude = []\n\n[lint]\n# Target version 14 of PostgreSQL by default\npostgres-target-version = 14\n\n# Enable all rules by default\nselect = []\n\n# Disable no rules by default\nignore = []\n\n# Include all files by default\ninclude = []\n\n# Exclude no files by default\nexclude = []\n\n# Ignore suppressing violations that are marked as `noqa` by default\nignore-noqa = false\n\n# Disallowed schemas\ndisallowed-schemas = []\n\n# Allowed extensions\nallowed-extensions = []\n\n# Allowed languages\nallowed-languages = []\n\n# Do not fix violations automatically\nfix = false\n\n# Consider all rules as fixable\nfixable = []\n\n# Consider all rules as fixable\nunfixable = []\n\n# Disallowed data types\ndisallowed-data-types = []\n\n# Required columns\nrequired-columns = []\n\n# Suffix Timestamp columns with `_at` by default\ntimestamp-column-suffix = \"_at\"\n\n# Suffix Date columns with suffix `_date` by default\ndate-column-suffix = \"_date\"\n\n# Allow nay naming convention for partitions by default\nregex-partition = \"^.+$\"\n\n# Allow all any naming convention for indexes by default\nregex-index = \"^.+$\"\n\n# Allow any naming convention for primary key constraints by default\nregex-constraint-primary-key = \"^.+$\"\n\n# ALlow any naming convention for unique keys by default\nregex-constraint-unique-key = \"^.+$\"\n\n# Allow any naming convention for foreign keys by default\nregex-constraint-foreign-key = \"^.+$\"\n\n# Allow any naming convention for check constraints by default\nregex-constraint-check = \"^.+$\"\n\n# Allow any naming convention for exclusion constraints by default\nregex-constraint-exclusion = \"^.+$\"\n\n# Allow any naming convention for sequences by default\nregex-sequence = \"^.+$\"\n\n[format]\n# Include all files by default\ninclude = []\n\n# Exclude no files by default\nexclude = []\n\n# Comma at the beginning of an item by default\ncomma-at-beginning = true\n\n# New line before semicolon false by default\nnew-line-before-semicolon = false\n\n# Remove pg_catalog from functions by default\nremove-pg-catalog-from-functions = true\n\n# Separate statements by a certain number by of new line, 1 by default\nlines-between-statements = 1\n\n# Check if files would have been modified, returning a non-zero exit code\ncheck = false\n\n# Report if files would have been modified, returning a non-zero exit code as well the difference between the current file and how the formatted file would look like\ndiff = false\n\n# Whether to read the cache.\nno-cache = false\n```\n\nSome configuration options can be supplied via CLI arguments such as `--check`, `--diff`, `--fix`.\n\n```bash\npgrubic format --check\n```\n\n```bash\npgrubic format --diff\n```\n\n```bash\npgrubic lint --fix\n```\n\n## Rules\n\nThere are 100+ rules. All rules are enabled by default. For a complete list, see [here](https://bolajiwahab.github.io/pgrubic/rules/).\n\n## Formatting style\n\npgrubic uses **River** style code formatting.\n\n## Contributing\n\nWe welcome and greatly appreciate contributions. If you would like to contribute, please see the [contributing guidelines](https://github.com/bolajiwahab/pgrubic/blob/main/docs/docs/contributing.md).\n\n## Support\n\nEncountering issues? Take a look at the existing GitHub [issues](https://github.com/bolajiwahab/pgrubic/issues), and don't hesitate to open a new one.\n\n## Acknowledgments\n\npgrubic is inspired by a number of similar tools such as [Strong Migrations](https://github.com/ankane/strong_migrations), [squabble](https://github.com/erik/squabble),\n[squawk](https://github.com/sbdchd/squawk), [pgextwlist](https://github.com/dimitri/pgextwlist), [Don't_Do_This](https://wiki.postgresql.org/wiki/Don't_Do_This)\nand [schemalint](https://github.com/kristiandupont/schemalint).\n\npgrubic is built upon the shoulders of:\n\n- [pglast](https://github.com/lelit/pglast) - Python bindings to libpg_query\n- [libpg_query](https://github.com/pganalyze/libpg_query) - PostgreSQL parser outside of the server environment\n\n## License\n\npgrubic is released under GPL-3.0 license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbolajiwahab%2Fpgrubic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbolajiwahab%2Fpgrubic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbolajiwahab%2Fpgrubic/lists"}