postgresql — Cursor rule: safe migrations and indexing
A Cursor rule that pins down how the agent writes PostgreSQL: parameterized queries, TIMESTAMPTZ, indexes on foreign keys. Useful once the agent starts touching your SQL.
.cursor/rules/postgresql.mdcWhat postgresql does
The rule attaches to **/*.sql, **/migrations/**/*.sql, **/schema.sql and **/seed.sql, so it kicks in wherever the agent edits schema or queries. On the schema side it asks for TIMESTAMPTZ rather than a timestamp without a zone, UUID for public IDs and BIGSERIAL for internal keys, NOT NULL unless nullability is deliberate, and an explicit ON DELETE on every foreign key.
Queries must be parameterized, columns listed by name instead of SELECT *, and large result sets capped with LIMIT. Complex queries get an EXPLAIN ANALYZE pass before they ship. Indexing: one index per foreign key column, CREATE INDEX CONCURRENTLY on live tables, partial indexes for the subsets you filter often.
Migrations follow versioned names like V001__create_table.sql. Adding a wide column is a multi-step job with a backfill, and rollback gets tested before deploy. A separate section bans SELECT *, string-built SQL, schema changes during peak traffic, plaintext passwords and TRUNCATE in application code. Drop the file at .cursor/rules/postgresql.mdc; other editors read their own path, so the rule will not load there.
What it helps with
- catch
SELECT *and string-built SQL before review - add a column to a live table without locking it
- get an index onto every foreign key column
- move new schema from TIMESTAMP to TIMESTAMPTZ
- test a migration rollback before deploy
Example prompts for the agent
- Write migration
V007__add_status.sqlthat adds a column to the orders table without locking it. - Rewrite this query with parameters and drop the
SELECT *. - Run EXPLAIN ANALYZE on the monthly orders query and suggest indexes.
How to install postgresql
Manually: put the files in place
.cursor/rules/postgresql.mdcFrontmatter: description, globs, alwaysApply
Manually: put the files in place
.claude/rules/postgresql.mdThe paths frontmatter field limits the files: move globs from the source into paths
AGENTS.md
Codex reads AGENTS.md: paste the rule text there
Manually: put the files in place
.github/instructions/postgresql.instructions.mdThe applyTo field sets which files it applies to: move globs from the source into applyTo
Manually: put the files in place
.devin/rules/postgresql.mdManually: put the files in place
.clinerules/postgresql.mdStep by step, with commands for each platform: Cursor rules: .mdc files, four modes and what replaced .cursorrules
Questions about postgresql
How do I install the postgresql rule in Cursor?
Create .cursor/rules/postgresql.mdc in your project and paste the rule contents into it. Cursor then applies it to files matching the globs.
What does the postgresql rule do?
It sets conventions for schema, queries, indexes, migrations and transactions in PostgreSQL. It also lists what the agent must avoid, such as SELECT * and string-built SQL.
Which files does the rule apply to?
**/*.sql, **/migrations/**/*.sql, **/schema.sql and **/seed.sql. Outside those paths it stays inactive.
Source text
postgresql.mdc · CC0-1.0
--- description: "PostgreSQL production rules. Safe migrations, parameterized queries, TIMESTAMPTZ, proper indexing strategy." globs: **/*.sql, **/migrations/**/*.sql, **/schema.sql, **/seed.sql alwaysApply: false --- # PostgreSQL Rules Expert PostgreSQL developer. Safe migrations, parameterized queries, proper indexing. ## Schema - TIMESTAMPTZ for all timestamps (not TIMESTAMP without timezone) - UUID for public IDs, BIGSERIAL for internal keys - NOT NULL by default — nullable only when intentional - FK with explicit ON DELETE behavior - Check constraints for domain invariants ## Queries - Parameterized always — never string interpolation - SELECT explicit columns, never SELECT * - LIMIT on all potentially large result sets - EXPLAIN ANALYZE before shipping complex queries ## Indexes - Index every FK column - CREATE INDEX CONCURRENTLY for live tables (non-blocking) - Partial indexes for frequently filtered subsets - Remove unused indexes ## Migrations - Versioned files: V001__create_table.sql - Large column additions: multi-step with backfill - Test rollback before deploying ## Transactions - Explicit BEGIN/COMMIT for multi-statement changes - statement_timeout to prevent runaway queries - SELECT ... FOR UPDATE for row locking ## Forbidden - No SELECT * - No string-interpolated SQL - No schema changes during peak traffic - No plaintext passwords in DB - No TRUNCATE in app code
© PatrickJS · CC0-1.0 · PatrickJS/awesome-cursorrules