All rules

Schema

postgresql/require-table-columns

Require every `CREATE TABLE` to include a configured set of columns.

  • Type problem
  • Recommended off
  • Fixable no

Why this matters

Useful for enforcing project-wide schema conventions — every table must carry the tenant key, audit columns (`created_at`, `created_by`, `updated_at`, `updated_by`), or any other set the project standardises on. The rule inspects every `CREATE TABLE` and reports one diagnostic per missing column. The `columns` option is required and lists the default required column names. `overrides` is an array of `{ pattern, columns }` entries — the first regex that matches the table name replaces the column list entirely (so an override of `[a, b]` does *not* require the default columns as well). `exclude` is a regex string for tables that should be skipped completely (e.g. audit / log tables, materialised views built via `CREATE TABLE AS`).

Examples

Incorrect

Incorrect
CREATE TABLE orders (
  id         bigserial PRIMARY KEY,
  created_at timestamptz NOT NULL DEFAULT current_timestamp,
  updated_at timestamptz NOT NULL DEFAULT current_timestamp
);

Correct

Correct
CREATE TABLE orders (
  id         bigserial PRIMARY KEY,
  tenant_id  bigint NOT NULL,
  created_at timestamptz NOT NULL DEFAULT current_timestamp,
  created_by bigint NOT NULL,
  updated_at timestamptz NOT NULL DEFAULT current_timestamp,
  updated_by bigint NOT NULL
);

Configure it

// eslint.config.js
import postgresql from "eslint-plugin-postgresql";

export default [
  {
    files: ["**/*.sql"],
    languageOptions: {
      parser: postgresql.configs.recommended.languageOptions.parser,
    },
    plugins: { postgresql },
    rules: {
      "postgresql/require-table-columns": [
        "warn",
        {
          columns: [],
          overrides: [],
          exclude: "",
        },
      ],
    },
  },
];

Options

columns string[]
Required. The default list of column names that every `CREATE TABLE` must declare.
overrides { pattern: string; columns: string[] }[]
Per-table-pattern overrides. The first entry whose `pattern` regex matches the table name replaces the default `columns` list entirely. Use this for tables that legitimately need a different set (e.g. `^.+_temporal$` for append-only history tables that have no `updated_by`).
exclude string (regex)
Tables whose name matches this regex are skipped completely. Useful for audit / log tables that intentionally have a different schema.
Try this rule

Edit the SQL — only require-table-columns is enabled.

Pre-filled with the first incorrect example. Toggle off in the rule shelf to see how the diagnostic disappears.

0 errors 0 warnings parse 0ms · rules 0ms
Diagnostics

No issues found.

2 rules enabled.

Rule under test require-table-columns — plus no-syntax-error as a safety net.
eslint-plugin-postgresql

An ESLint plugin that lints .sql files with real PostgreSQL grammar and a curated set of best-practice rules.

© 2026 eslint-plugin-postgresql contributors Built on libpg-query · PostgreSQL 17