@toichubek/pg-ddl-extractor 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +424 -297
- package/dist/changelog.d.ts +1 -0
- package/dist/changelog.js +227 -0
- package/dist/cli/changelog.d.ts +2 -0
- package/dist/cli/changelog.js +4 -0
- package/dist/cli/deps.d.ts +2 -0
- package/dist/cli/deps.js +4 -0
- package/dist/cli/docs.d.ts +2 -0
- package/dist/cli/docs.js +4 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +4 -0
- package/dist/cli/lint.d.ts +2 -0
- package/dist/cli/lint.js +4 -0
- package/dist/cli/search.d.ts +2 -0
- package/dist/cli/search.js +4 -0
- package/dist/cli/size-report.d.ts +2 -0
- package/dist/cli/size-report.js +4 -0
- package/dist/cli/snapshot-diff.d.ts +2 -0
- package/dist/cli/snapshot-diff.js +4 -0
- package/dist/cli/stats.d.ts +2 -0
- package/dist/cli/stats.js +4 -0
- package/dist/cli/validate.d.ts +2 -0
- package/dist/cli/validate.js +4 -0
- package/dist/cli/watch.d.ts +2 -0
- package/dist/cli/watch.js +4 -0
- package/dist/compare.d.ts +17 -0
- package/dist/compare.js +303 -0
- package/dist/data-extractor.d.ts +16 -0
- package/dist/data-extractor.js +143 -0
- package/dist/deps.d.ts +1 -0
- package/dist/deps.js +308 -0
- package/dist/diff.js +53 -20
- package/dist/docs-generator.d.ts +49 -0
- package/dist/docs-generator.js +278 -0
- package/dist/docs.d.ts +1 -0
- package/dist/docs.js +157 -0
- package/dist/extract.js +142 -21
- package/dist/extractor.d.ts +17 -1
- package/dist/extractor.js +115 -18
- package/dist/index.d.ts +17 -3
- package/dist/index.js +39 -1
- package/dist/init.d.ts +1 -0
- package/dist/init.js +166 -0
- package/dist/json-exporter.d.ts +105 -0
- package/dist/json-exporter.js +463 -0
- package/dist/lint.d.ts +1 -0
- package/dist/lint.js +145 -0
- package/dist/linter.d.ts +32 -0
- package/dist/linter.js +269 -0
- package/dist/migrate.js +133 -4
- package/dist/migration-generator.d.ts +18 -1
- package/dist/migration-generator.js +348 -5
- package/dist/migration-tracker.d.ts +28 -0
- package/dist/migration-tracker.js +99 -0
- package/dist/pool.d.ts +22 -0
- package/dist/pool.js +69 -0
- package/dist/pre-check.d.ts +24 -0
- package/dist/pre-check.js +242 -0
- package/dist/progress.d.ts +32 -0
- package/dist/progress.js +84 -0
- package/dist/rc-config.d.ts +33 -0
- package/dist/rc-config.js +184 -0
- package/dist/search.d.ts +1 -0
- package/dist/search.js +146 -0
- package/dist/size-report.d.ts +1 -0
- package/dist/size-report.js +231 -0
- package/dist/snapshot-diff.d.ts +1 -0
- package/dist/snapshot-diff.js +182 -0
- package/dist/snapshot.d.ts +30 -0
- package/dist/snapshot.js +230 -0
- package/dist/stats.d.ts +1 -0
- package/dist/stats.js +213 -0
- package/dist/validate.d.ts +1 -0
- package/dist/validate.js +328 -0
- package/dist/watch.d.ts +1 -0
- package/dist/watch.js +244 -0
- package/package.json +28 -2
package/README.md
CHANGED
|
@@ -1,422 +1,549 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PostgreSQL DDL Extractor
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@toichubek/pg-ddl-extractor)
|
|
4
4
|
[](https://www.npmjs.com/package/@toichubek/pg-ddl-extractor)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
|
|
8
|
-
Extracts full database structure (DDL) from PostgreSQL and organizes it into a clean folder structure for Git version control.
|
|
8
|
+
Extracts full database structure (DDL) from PostgreSQL and organizes it into a clean folder structure for Git version control. Includes diffing, migration generation, linting, documentation, and more.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Quick Start
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
```bash
|
|
13
|
+
npm install -g @toichubek/pg-ddl-extractor
|
|
14
|
+
pg-ddl-init # Create project structure & .env template
|
|
15
|
+
# Edit .env with your database credentials
|
|
16
|
+
pg-ddl-extract --env dev # Extract schema → sql/dev/
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
13
20
|
|
|
14
21
|
```bash
|
|
15
|
-
#
|
|
22
|
+
# Global (recommended)
|
|
16
23
|
npm install -g @toichubek/pg-ddl-extractor
|
|
17
24
|
|
|
18
|
-
#
|
|
25
|
+
# Local
|
|
19
26
|
npm install --save-dev @toichubek/pg-ddl-extractor
|
|
20
27
|
```
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
## All Commands
|
|
30
|
+
|
|
31
|
+
| Command | Description | Output |
|
|
32
|
+
|---------|-------------|--------|
|
|
33
|
+
| `pg-ddl-extract` | Extract DDL from database | `sql/<env>/` |
|
|
34
|
+
| `pg-ddl-diff` | Compare DEV vs PROD schemas | console / `sql/reports/` |
|
|
35
|
+
| `pg-ddl-migrate` | Generate migration SQL | `sql/migrations/` |
|
|
36
|
+
| `pg-ddl-init` | Initialize project structure | `.env.example`, config, `sql/` |
|
|
37
|
+
| `pg-ddl-lint` | Lint schema for common issues | console |
|
|
38
|
+
| `pg-ddl-validate` | Validate conventions & consistency | console |
|
|
39
|
+
| `pg-ddl-deps` | FK dependency graph & creation order | console / `.mmd` / `.dot` |
|
|
40
|
+
| `pg-ddl-size` | Storage size analysis | console / JSON |
|
|
41
|
+
| `pg-ddl-stats` | Database statistics overview | console |
|
|
42
|
+
| `pg-ddl-search` | Search extracted SQL files | console |
|
|
43
|
+
| `pg-ddl-docs` | Generate Markdown documentation | `sql/docs/` |
|
|
44
|
+
| `pg-ddl-changelog` | Git-based schema changelog | console / Markdown |
|
|
45
|
+
| `pg-ddl-snapshot-diff` | Compare schema between Git refs | console / Markdown |
|
|
46
|
+
| `pg-ddl-watch` | Auto re-extract on schema changes | continuous |
|
|
47
|
+
|
|
48
|
+
## Output Structure
|
|
27
49
|
|
|
28
50
|
```
|
|
29
|
-
|
|
30
|
-
├──
|
|
31
|
-
├──
|
|
32
|
-
├──
|
|
33
|
-
│
|
|
34
|
-
│
|
|
35
|
-
│ │ ├──
|
|
36
|
-
│ │
|
|
37
|
-
│
|
|
38
|
-
│ ├──
|
|
39
|
-
│ ├──
|
|
40
|
-
│
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
│ ├── materialized_views/
|
|
55
|
-
│ ├── sequences/
|
|
56
|
-
│ ├── triggers/
|
|
57
|
-
│ ├── types/
|
|
58
|
-
│ └── indexes/
|
|
59
|
-
└── prod/
|
|
60
|
-
└── ... (same structure)
|
|
51
|
+
sql/
|
|
52
|
+
├── dev/ ← pg-ddl-extract --env dev
|
|
53
|
+
│ ├── _full_dump.sql
|
|
54
|
+
│ ├── schemas/
|
|
55
|
+
│ │ └── public.sql
|
|
56
|
+
│ ├── tables/
|
|
57
|
+
│ │ ├── public.users.sql
|
|
58
|
+
│ │ └── public.orders.sql
|
|
59
|
+
│ ├── functions/
|
|
60
|
+
│ ├── views/
|
|
61
|
+
│ ├── materialized_views/
|
|
62
|
+
│ ├── sequences/
|
|
63
|
+
│ ├── triggers/
|
|
64
|
+
│ ├── types/
|
|
65
|
+
│ └── indexes/
|
|
66
|
+
├── prod/ ← pg-ddl-extract --env prod
|
|
67
|
+
│ └── ... (same structure)
|
|
68
|
+
├── docs/ ← pg-ddl-docs
|
|
69
|
+
│ ├── schema_dev.md
|
|
70
|
+
│ └── erd_dev.md
|
|
71
|
+
├── reports/ ← pg-ddl-diff --report
|
|
72
|
+
│ └── diff_report.md
|
|
73
|
+
└── migrations/ ← pg-ddl-migrate
|
|
74
|
+
├── 20260207_120000_dev_to_prod.sql
|
|
75
|
+
└── 20260207_120000_rollback.sql
|
|
61
76
|
```
|
|
62
77
|
|
|
63
78
|
## What Gets Extracted
|
|
64
79
|
|
|
65
|
-
| Object
|
|
66
|
-
|
|
67
|
-
| **Tables**
|
|
68
|
-
| **Functions**
|
|
69
|
-
| **Views**
|
|
70
|
-
| **Materialized Views** | `CREATE MATERIALIZED VIEW`
|
|
71
|
-
| **Sequences**
|
|
72
|
-
| **Triggers**
|
|
73
|
-
| **Types**
|
|
74
|
-
| **Indexes**
|
|
75
|
-
| **Schemas**
|
|
80
|
+
| Object | Includes |
|
|
81
|
+
|--------|----------|
|
|
82
|
+
| **Tables** | Columns, PK, FK, UNIQUE, CHECK, defaults, comments |
|
|
83
|
+
| **Functions** | Full `CREATE FUNCTION` via `pg_get_functiondef()` |
|
|
84
|
+
| **Views** | `CREATE OR REPLACE VIEW` |
|
|
85
|
+
| **Materialized Views** | `CREATE MATERIALIZED VIEW` |
|
|
86
|
+
| **Sequences** | INCREMENT, MIN, MAX, START, CYCLE |
|
|
87
|
+
| **Triggers** | Timing, events, action |
|
|
88
|
+
| **Types** | Enum and composite types |
|
|
89
|
+
| **Indexes** | Non-constraint indexes only |
|
|
90
|
+
| **Schemas** | `CREATE SCHEMA IF NOT EXISTS` |
|
|
76
91
|
|
|
77
|
-
|
|
92
|
+
---
|
|
78
93
|
|
|
79
|
-
|
|
80
|
-
# Install dependencies
|
|
81
|
-
npm install
|
|
94
|
+
## Core Commands
|
|
82
95
|
|
|
83
|
-
|
|
84
|
-
cp .env.example .env
|
|
85
|
-
```
|
|
96
|
+
### pg-ddl-extract
|
|
86
97
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
```env
|
|
90
|
-
DEV_DB_HOST=localhost
|
|
91
|
-
DEV_DB_PORT=5432
|
|
92
|
-
DEV_DB_NAME=my_database
|
|
93
|
-
DEV_DB_USER=postgres
|
|
94
|
-
DEV_DB_PASSWORD=secret
|
|
98
|
+
Extract database DDL into organized SQL files.
|
|
95
99
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
```bash
|
|
101
|
+
pg-ddl-extract --env dev # Extract DEV → sql/dev/
|
|
102
|
+
pg-ddl-extract --env prod # Extract PROD → sql/prod/
|
|
103
|
+
pg-ddl-extract --host localhost --database mydb --user postgres
|
|
104
|
+
|
|
105
|
+
# Filters
|
|
106
|
+
pg-ddl-extract --env dev --schema public,auth # Only specific schemas
|
|
107
|
+
pg-ddl-extract --env dev --tables public.users # Only specific tables
|
|
108
|
+
pg-ddl-extract --env dev --exclude-schema test # Exclude schemas
|
|
109
|
+
pg-ddl-extract --env dev --exclude-tables public.logs
|
|
110
|
+
|
|
111
|
+
# Data export
|
|
112
|
+
pg-ddl-extract --env dev --with-data countries,currencies --max-rows 5000
|
|
113
|
+
|
|
114
|
+
# Formats & modes
|
|
115
|
+
pg-ddl-extract --env dev --format json # Export as JSON
|
|
116
|
+
pg-ddl-extract --env dev --incremental # Only changed objects
|
|
117
|
+
pg-ddl-extract --env dev --progress # Show progress bar
|
|
118
|
+
pg-ddl-extract --env dev --output /custom/path # Custom output
|
|
101
119
|
```
|
|
102
120
|
|
|
103
|
-
|
|
121
|
+
**Options:**
|
|
122
|
+
|
|
123
|
+
| Flag | Description | Default |
|
|
124
|
+
|------|-------------|---------|
|
|
125
|
+
| `--env <env>` | Environment (dev/prod) | `dev` |
|
|
126
|
+
| `--host <host>` | Database host | from .env |
|
|
127
|
+
| `--port <port>` | Database port | `5432` |
|
|
128
|
+
| `--database <db>` | Database name | from .env |
|
|
129
|
+
| `--user <user>` | Database user | from .env |
|
|
130
|
+
| `--password <pass>` | Database password | from .env |
|
|
131
|
+
| `--output <path>` | Output directory | `sql/<env>` |
|
|
132
|
+
| `--schema <list>` | Include schemas (comma-separated) | all |
|
|
133
|
+
| `--tables <list>` | Include tables (schema.table) | all |
|
|
134
|
+
| `--exclude-schema <list>` | Exclude schemas | none |
|
|
135
|
+
| `--exclude-tables <list>` | Exclude tables | none |
|
|
136
|
+
| `--with-data <list>` | Tables to export INSERT data | none |
|
|
137
|
+
| `--max-rows <n>` | Max rows per data table | `10000` |
|
|
138
|
+
| `--format <fmt>` | Output: `sql` or `json` | `sql` |
|
|
139
|
+
| `--incremental` | Only re-extract changed objects | off |
|
|
140
|
+
| `--progress` | Show progress bar | off |
|
|
141
|
+
|
|
142
|
+
### pg-ddl-diff
|
|
143
|
+
|
|
144
|
+
Compare schemas between environments.
|
|
104
145
|
|
|
105
|
-
|
|
146
|
+
```bash
|
|
147
|
+
pg-ddl-diff # Compare DEV vs PROD
|
|
148
|
+
pg-ddl-diff --report # Save markdown + HTML report
|
|
149
|
+
pg-ddl-diff --side-by-side # Side-by-side HTML diff
|
|
150
|
+
pg-ddl-diff --dev /path/to/dev --prod /path/to/prod
|
|
151
|
+
pg-ddl-diff --envs dev,staging,prod # Multi-environment compare
|
|
152
|
+
```
|
|
106
153
|
|
|
107
|
-
|
|
154
|
+
**Options:**
|
|
108
155
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
156
|
+
| Flag | Description | Default |
|
|
157
|
+
|------|-------------|---------|
|
|
158
|
+
| `--report` | Save markdown/HTML reports | off |
|
|
159
|
+
| `--side-by-side` | Side-by-side HTML diff | off |
|
|
160
|
+
| `--sql-dir <path>` | SQL directory | `./sql` |
|
|
161
|
+
| `--dev <path>` | Dev schema path | auto |
|
|
162
|
+
| `--prod <path>` | Prod schema path | auto |
|
|
163
|
+
| `--envs <list>` | Compare multiple envs | dev,prod |
|
|
116
164
|
|
|
117
|
-
|
|
118
|
-
PROD_DB_HOST=prod-server.example.com
|
|
119
|
-
PROD_DB_PORT=5432
|
|
120
|
-
PROD_DB_NAME=my_database
|
|
121
|
-
PROD_DB_USER=readonly_user
|
|
122
|
-
PROD_DB_PASSWORD=secret
|
|
165
|
+
### pg-ddl-migrate
|
|
123
166
|
|
|
124
|
-
|
|
125
|
-
|
|
167
|
+
Generate migration SQL from DEV to PROD.
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
pg-ddl-migrate # Generate migration
|
|
171
|
+
pg-ddl-migrate --with-rollback # With rollback script
|
|
172
|
+
pg-ddl-migrate --dry-run # Preview without saving
|
|
173
|
+
pg-ddl-migrate --interactive # Review each change
|
|
174
|
+
pg-ddl-migrate --pre-check # Run health checks first
|
|
175
|
+
pg-ddl-migrate --track --database mydb --user postgres # Track in DB
|
|
176
|
+
pg-ddl-migrate --history --database mydb --user postgres # View history
|
|
126
177
|
```
|
|
127
178
|
|
|
128
|
-
|
|
179
|
+
**Options:**
|
|
129
180
|
|
|
130
|
-
|
|
181
|
+
| Flag | Description | Default |
|
|
182
|
+
|------|-------------|---------|
|
|
183
|
+
| `--sql-dir <path>` | SQL directory | `./sql` |
|
|
184
|
+
| `--dev <path>` | Dev schema path | auto |
|
|
185
|
+
| `--prod <path>` | Prod schema path | auto |
|
|
186
|
+
| `--with-rollback` | Generate rollback script | off |
|
|
187
|
+
| `--dry-run` | Preview only | off |
|
|
188
|
+
| `--interactive` | Review each change | off |
|
|
189
|
+
| `--pre-check` | Health checks before migration | off |
|
|
190
|
+
| `--history` | Show migration history | off |
|
|
191
|
+
| `--track` | Record migration in DB | off |
|
|
131
192
|
|
|
132
|
-
|
|
133
|
-
- `--env <environment>` - Environment name (dev or prod) - default: `dev`
|
|
134
|
-
- `--host <host>` - Database host
|
|
135
|
-
- `--port <port>` - Database port - default: `5432`
|
|
136
|
-
- `--database <database>` - Database name (required with --host)
|
|
137
|
-
- `--user <user>` - Database user (required with --host)
|
|
138
|
-
- `--password <password>` - Database password
|
|
139
|
-
- `--output <path>` - Custom output directory path
|
|
140
|
-
- `--help` - Display help
|
|
141
|
-
- `--version` - Display version
|
|
193
|
+
### pg-ddl-init
|
|
142
194
|
|
|
143
|
-
|
|
144
|
-
- `--report` - Generate markdown and HTML reports
|
|
145
|
-
- `--sql-dir <path>` - Path to SQL directory - default: `./sql`
|
|
146
|
-
- `--dev <path>` - Path to dev schema directory
|
|
147
|
-
- `--prod <path>` - Path to prod schema directory
|
|
148
|
-
- `--help` - Display help
|
|
149
|
-
- `--version` - Display version
|
|
195
|
+
Initialize project structure with config templates.
|
|
150
196
|
|
|
151
|
-
|
|
152
|
-
-
|
|
153
|
-
|
|
154
|
-
- `--prod <path>` - Path to prod schema directory
|
|
155
|
-
- `--help` - Display help
|
|
156
|
-
- `--version` - Display version
|
|
197
|
+
```bash
|
|
198
|
+
pg-ddl-init # Create .env.example, config, sql/
|
|
199
|
+
```
|
|
157
200
|
|
|
158
|
-
|
|
201
|
+
---
|
|
159
202
|
|
|
160
|
-
|
|
203
|
+
## Analysis Commands
|
|
161
204
|
|
|
162
|
-
|
|
163
|
-
# Extract DEV database → saves to ./sql/dev/
|
|
164
|
-
pg-ddl-extract --env dev
|
|
205
|
+
### pg-ddl-lint
|
|
165
206
|
|
|
166
|
-
|
|
167
|
-
pg-ddl-extract --env prod
|
|
207
|
+
Lint your database schema for common issues and best practices.
|
|
168
208
|
|
|
169
|
-
|
|
170
|
-
pg-ddl-
|
|
209
|
+
```bash
|
|
210
|
+
pg-ddl-lint --env dev
|
|
211
|
+
pg-ddl-lint --env prod
|
|
212
|
+
pg-ddl-lint --host localhost --database mydb --user postgres
|
|
213
|
+
```
|
|
171
214
|
|
|
172
|
-
|
|
173
|
-
pg-ddl-extract --env dev --output /custom/path
|
|
215
|
+
**Lint Rules:**
|
|
174
216
|
|
|
175
|
-
|
|
176
|
-
|
|
217
|
+
| Rule | Severity | Description |
|
|
218
|
+
|------|----------|-------------|
|
|
219
|
+
| `no-primary-key` | Error | Tables without PRIMARY KEY |
|
|
220
|
+
| `missing-fk-index` | Warning | FK columns without index (slow JOINs) |
|
|
221
|
+
| `duplicate-index` | Warning | Indexes with identical column sets |
|
|
222
|
+
| `unused-index` | Info | Indexes never scanned |
|
|
223
|
+
| `no-table-comment` | Info | Tables without COMMENT |
|
|
224
|
+
| `unowned-sequence` | Info | Sequences not owned by any column |
|
|
177
225
|
|
|
178
|
-
|
|
179
|
-
pg-ddl-diff --report
|
|
226
|
+
Exit code `1` if any errors found (useful for CI/CD).
|
|
180
227
|
|
|
181
|
-
|
|
182
|
-
pg-ddl-diff --dev /path/to/dev --prod /path/to/prod
|
|
228
|
+
### pg-ddl-validate
|
|
183
229
|
|
|
184
|
-
|
|
185
|
-
pg-ddl-migrate
|
|
230
|
+
Validate schema consistency and conventions.
|
|
186
231
|
|
|
187
|
-
|
|
188
|
-
pg-ddl-
|
|
232
|
+
```bash
|
|
233
|
+
pg-ddl-validate --env dev
|
|
234
|
+
pg-ddl-validate --env dev --sql-dir ./sql # Check files vs live DB
|
|
235
|
+
pg-ddl-validate --env dev --strict # Warnings become errors
|
|
236
|
+
pg-ddl-validate --host localhost --database mydb --user postgres
|
|
189
237
|
```
|
|
190
238
|
|
|
191
|
-
|
|
239
|
+
**Validation Checks:**
|
|
192
240
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
241
|
+
| Check | Severity | Description |
|
|
242
|
+
|-------|----------|-------------|
|
|
243
|
+
| `no-primary-key` | Error | Tables without PRIMARY KEY |
|
|
244
|
+
| `wide-table` | Warning | Tables with >20 columns |
|
|
245
|
+
| `no-indexes` | Warning | Tables with no indexes |
|
|
246
|
+
| `stale-file` | Warning | Extracted files for removed objects |
|
|
247
|
+
| `missing-extract` | Warning | DB objects not in extracted files |
|
|
248
|
+
| `vague-column-name` | Info | Generic names like "data", "info" |
|
|
249
|
+
| `nullable-fk` | Info | Nullable foreign key columns |
|
|
196
250
|
|
|
197
|
-
|
|
198
|
-
$env:DEV_DB_HOST="localhost"; $env:DEV_DB_NAME="mydb"; pg-ddl-extract --env dev
|
|
251
|
+
Exit code `1` on errors (or warnings in `--strict` mode).
|
|
199
252
|
|
|
200
|
-
|
|
201
|
-
set DEV_DB_HOST=localhost && set DEV_DB_NAME=mydb && pg-ddl-extract --env dev
|
|
202
|
-
```
|
|
253
|
+
### pg-ddl-deps
|
|
203
254
|
|
|
204
|
-
|
|
255
|
+
Analyze FK dependencies and get safe table creation order.
|
|
205
256
|
|
|
206
257
|
```bash
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
npm run migrate
|
|
258
|
+
pg-ddl-deps --env dev # Show dependency graph
|
|
259
|
+
pg-ddl-deps --env dev --order # Topological creation order
|
|
260
|
+
pg-ddl-deps --env dev --mermaid --output deps.mmd # Mermaid ERD export
|
|
261
|
+
pg-ddl-deps --env dev --dot --output deps.dot # Graphviz DOT export
|
|
262
|
+
pg-ddl-deps --host localhost --database mydb --user postgres
|
|
213
263
|
```
|
|
214
264
|
|
|
215
|
-
###
|
|
265
|
+
### pg-ddl-size
|
|
216
266
|
|
|
217
|
-
|
|
218
|
-
import { Client } from "pg";
|
|
219
|
-
import {
|
|
220
|
-
SqlFileWriter,
|
|
221
|
-
DdlExtractor,
|
|
222
|
-
compareDdl,
|
|
223
|
-
generateMigration,
|
|
224
|
-
} from "@toichubek/pg-ddl-extractor";
|
|
267
|
+
Detailed storage analysis by schema, table, and index.
|
|
225
268
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
269
|
+
```bash
|
|
270
|
+
pg-ddl-size --env dev # Full size report
|
|
271
|
+
pg-ddl-size --env dev --top 10 # Top 10 largest
|
|
272
|
+
pg-ddl-size --env dev --json --output size.json # Export as JSON
|
|
273
|
+
pg-ddl-size --host localhost --database mydb --user postgres
|
|
274
|
+
```
|
|
229
275
|
|
|
230
|
-
|
|
231
|
-
const extractor = new DdlExtractor(client, writer);
|
|
232
|
-
await extractor.extractAll();
|
|
276
|
+
### pg-ddl-stats
|
|
233
277
|
|
|
234
|
-
|
|
235
|
-
const summary = compareDdl("./sql");
|
|
236
|
-
console.log(summary);
|
|
278
|
+
Database statistics overview (table counts, sizes, activity).
|
|
237
279
|
|
|
238
|
-
|
|
239
|
-
|
|
280
|
+
```bash
|
|
281
|
+
pg-ddl-stats --env dev
|
|
282
|
+
pg-ddl-stats --env prod
|
|
283
|
+
pg-ddl-stats --host localhost --database mydb --user postgres
|
|
240
284
|
```
|
|
241
285
|
|
|
242
|
-
|
|
286
|
+
### pg-ddl-search
|
|
287
|
+
|
|
288
|
+
Search across extracted SQL files with regex support.
|
|
243
289
|
|
|
244
290
|
```bash
|
|
245
|
-
#
|
|
246
|
-
|
|
291
|
+
pg-ddl-search "email" --env dev # Search for keyword
|
|
292
|
+
pg-ddl-search "user_id" -i # Case-insensitive
|
|
293
|
+
pg-ddl-search "created_at" --category tables # Only in tables
|
|
294
|
+
pg-ddl-search "DEFAULT now\(\)" --env dev # Regex patterns
|
|
295
|
+
pg-ddl-search "FOREIGN KEY" --sql-dir /path/to/sql
|
|
296
|
+
```
|
|
247
297
|
|
|
248
|
-
|
|
249
|
-
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Documentation Commands
|
|
301
|
+
|
|
302
|
+
### pg-ddl-docs
|
|
303
|
+
|
|
304
|
+
Auto-generate Markdown documentation from your database schema.
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
pg-ddl-docs --env dev # Generate → sql/docs/
|
|
308
|
+
pg-ddl-docs --env dev --diagram # With Mermaid ERD
|
|
309
|
+
pg-ddl-docs --env dev --output ./my-docs # Custom output
|
|
310
|
+
pg-ddl-docs --host localhost --database mydb --user postgres --diagram
|
|
250
311
|
```
|
|
251
312
|
|
|
252
|
-
|
|
313
|
+
Generated documentation includes:
|
|
314
|
+
- Table of contents with links
|
|
315
|
+
- Column details (type, nullable, default, PK/FK, comments)
|
|
316
|
+
- Table statistics (row estimate, size)
|
|
317
|
+
- Foreign key relationships
|
|
318
|
+
- Index definitions
|
|
319
|
+
- Views and functions listing
|
|
320
|
+
- Optional Mermaid ERD diagram
|
|
321
|
+
|
|
322
|
+
### pg-ddl-changelog
|
|
323
|
+
|
|
324
|
+
Generate a changelog from Git history of extracted SQL files.
|
|
253
325
|
|
|
254
326
|
```bash
|
|
255
|
-
#
|
|
256
|
-
|
|
327
|
+
pg-ddl-changelog # Recent schema changes
|
|
328
|
+
pg-ddl-changelog --env dev # Specific environment
|
|
329
|
+
pg-ddl-changelog --limit 10 # Last 10 commits
|
|
330
|
+
pg-ddl-changelog --markdown --output CHANGELOG.md # Export as Markdown
|
|
331
|
+
pg-ddl-changelog --sql-dir /path/to/sql
|
|
257
332
|
```
|
|
258
333
|
|
|
259
|
-
|
|
260
|
-
- Analyze differences between DEV and PROD
|
|
261
|
-
- Generate SQL migration commands (CREATE, ALTER, DROP)
|
|
262
|
-
- Save to `sql/migrations/YYYYMMDD_HHmmss_dev_to_prod.sql`
|
|
263
|
-
- Organize commands in correct execution order
|
|
264
|
-
- Add safety comments for manual review
|
|
334
|
+
### pg-ddl-snapshot-diff
|
|
265
335
|
|
|
266
|
-
|
|
336
|
+
Compare schema snapshots between Git commits or tags.
|
|
267
337
|
|
|
268
|
-
|
|
338
|
+
```bash
|
|
339
|
+
pg-ddl-snapshot-diff --from abc1234 --to def5678
|
|
340
|
+
pg-ddl-snapshot-diff --from v1.0.0 --to v2.0.0
|
|
341
|
+
pg-ddl-snapshot-diff --from HEAD~5 --to HEAD --env dev
|
|
342
|
+
pg-ddl-snapshot-diff --from main~10 --to main --output snapshot-report.md
|
|
269
343
|
```
|
|
270
|
-
═══════════════════════════════════════════════════════════
|
|
271
|
-
Migration Plan Generated
|
|
272
|
-
═══════════════════════════════════════════════════════════
|
|
273
344
|
|
|
274
|
-
|
|
345
|
+
---
|
|
275
346
|
|
|
276
|
-
|
|
277
|
-
🟢 Creates: 16
|
|
278
|
-
🔴 Drops: 57
|
|
279
|
-
🔄 Alters: 50
|
|
280
|
-
📊 Total: 123 commands
|
|
347
|
+
## Automation Commands
|
|
281
348
|
|
|
282
|
-
|
|
283
|
-
1. Review the migration file carefully
|
|
284
|
-
2. Test on staging environment
|
|
285
|
-
3. Backup production database
|
|
286
|
-
4. Run: psql -d your_db -f 20260207_052700_dev_to_prod.sql
|
|
349
|
+
### pg-ddl-watch
|
|
287
350
|
|
|
288
|
-
|
|
351
|
+
Automatically re-extract DDL when schema changes are detected.
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
pg-ddl-watch --env dev # Poll every 30s (default)
|
|
355
|
+
pg-ddl-watch --env dev --interval 60 # Custom interval
|
|
356
|
+
pg-ddl-watch --host localhost --database mydb --user postgres --interval 15
|
|
289
357
|
```
|
|
290
358
|
|
|
291
|
-
|
|
292
|
-
-
|
|
293
|
-
-
|
|
294
|
-
-
|
|
295
|
-
-
|
|
296
|
-
-
|
|
297
|
-
- **Indexes** - CREATE INDEX for new indexes
|
|
298
|
-
- **Drops** - DROP ... IF EXISTS CASCADE for removed objects
|
|
359
|
+
Watch mode:
|
|
360
|
+
- Full extraction on startup
|
|
361
|
+
- Polls for schema changes at configured interval
|
|
362
|
+
- Only re-extracts when changes detected (schema hash)
|
|
363
|
+
- Periodic heartbeat messages
|
|
364
|
+
- Press `Ctrl+C` to stop
|
|
299
365
|
|
|
300
|
-
|
|
366
|
+
---
|
|
301
367
|
|
|
302
|
-
|
|
303
|
-
```
|
|
304
|
-
═══════════════════════════════════════════════════════════
|
|
305
|
-
DEV vs PROD — DDL Comparison Report
|
|
306
|
-
═══════════════════════════════════════════════════════════
|
|
307
|
-
|
|
308
|
-
DEV objects: 48
|
|
309
|
-
PROD objects: 45
|
|
310
|
-
|
|
311
|
-
✅ Identical: 40
|
|
312
|
-
🔄 Modified: 3
|
|
313
|
-
🟢 Only DEV: 5
|
|
314
|
-
🔴 Only PROD: 2
|
|
315
|
-
|
|
316
|
-
───────────────────────────────────────────────────────────
|
|
317
|
-
🟢 EXISTS ONLY IN DEV (not yet in prod)
|
|
318
|
-
───────────────────────────────────────────────────────────
|
|
319
|
-
[tables] public.student_drafts
|
|
320
|
-
[functions] public.fn_calculate_scores
|
|
321
|
-
|
|
322
|
-
───────────────────────────────────────────────────────────
|
|
323
|
-
🔄 MODIFIED (different between dev and prod)
|
|
324
|
-
───────────────────────────────────────────────────────────
|
|
325
|
-
|
|
326
|
-
[tables] public.users
|
|
327
|
-
DEV [5]: email varchar(255) NOT NULL
|
|
328
|
-
PROD [5]: email varchar(150) NOT NULL
|
|
329
|
-
```
|
|
368
|
+
## Configuration
|
|
330
369
|
|
|
331
|
-
|
|
370
|
+
### Environment Variables (.env)
|
|
332
371
|
|
|
333
|
-
```
|
|
334
|
-
#
|
|
335
|
-
|
|
336
|
-
|
|
372
|
+
```env
|
|
373
|
+
# DEV database
|
|
374
|
+
DEV_DB_HOST=localhost
|
|
375
|
+
DEV_DB_PORT=5432
|
|
376
|
+
DEV_DB_NAME=my_database
|
|
377
|
+
DEV_DB_USER=postgres
|
|
378
|
+
DEV_DB_PASSWORD=secret
|
|
379
|
+
|
|
380
|
+
# PROD database
|
|
381
|
+
PROD_DB_HOST=prod-server.example.com
|
|
382
|
+
PROD_DB_PORT=5432
|
|
383
|
+
PROD_DB_NAME=my_database
|
|
384
|
+
PROD_DB_USER=readonly_user
|
|
385
|
+
PROD_DB_PASSWORD=secret
|
|
386
|
+
|
|
387
|
+
# Optional: SSH tunnel for PROD
|
|
388
|
+
PROD_SSH_HOST=your-server.com
|
|
389
|
+
PROD_SSH_PORT=22
|
|
390
|
+
PROD_SSH_USER=your_ssh_user
|
|
391
|
+
PROD_SSH_KEY_PATH=~/.ssh/id_rsa
|
|
392
|
+
|
|
393
|
+
# Optional: custom output directory
|
|
394
|
+
SQL_OUTPUT_DIR=/path/to/sql
|
|
337
395
|
```
|
|
338
396
|
|
|
339
|
-
|
|
397
|
+
**Priority:** CLI flags > Environment variables > .env file
|
|
398
|
+
|
|
399
|
+
### Configuration File
|
|
340
400
|
|
|
341
|
-
|
|
401
|
+
Create `.pg-ddl-extractor.json` in your project root:
|
|
342
402
|
|
|
343
403
|
```json
|
|
344
404
|
{
|
|
345
|
-
"
|
|
346
|
-
"
|
|
347
|
-
"
|
|
405
|
+
"defaults": {
|
|
406
|
+
"env": "dev",
|
|
407
|
+
"output": "./sql"
|
|
408
|
+
},
|
|
409
|
+
"extract": {
|
|
410
|
+
"excludeSchema": ["test", "temp"],
|
|
411
|
+
"excludeTables": ["public.logs", "public.cache"],
|
|
412
|
+
"maxRows": 5000
|
|
413
|
+
},
|
|
414
|
+
"migration": {
|
|
415
|
+
"withRollback": true
|
|
348
416
|
}
|
|
349
417
|
}
|
|
350
418
|
```
|
|
351
419
|
|
|
352
|
-
|
|
420
|
+
Supported config files (searched in order):
|
|
421
|
+
- `.pg-ddl-extractor.json`
|
|
422
|
+
- `.pg-ddl-extractor.yml`
|
|
423
|
+
- `.pg-ddl-extractor.yaml`
|
|
424
|
+
- `pg-ddl-extractor.config.json`
|
|
353
425
|
|
|
354
|
-
|
|
426
|
+
### Direct Connection
|
|
355
427
|
|
|
356
|
-
|
|
357
|
-
2. **Test on staging** - Run the migration on a staging database first
|
|
358
|
-
3. **Backup production** - Create a full backup before running on production
|
|
359
|
-
4. **Run migration**:
|
|
360
|
-
```bash
|
|
361
|
-
psql -h prod-host -U db_user -d database_name -f sql/migrations/YYYYMMDD_HHmmss_dev_to_prod.sql
|
|
362
|
-
```
|
|
428
|
+
All commands support direct connection flags (no .env needed):
|
|
363
429
|
|
|
364
|
-
|
|
430
|
+
```bash
|
|
431
|
+
pg-ddl-extract --host localhost --port 5432 --database mydb --user postgres --password secret
|
|
432
|
+
```
|
|
365
433
|
|
|
366
|
-
|
|
367
|
-
- Uses `IF EXISTS` for DROP commands
|
|
368
|
-
- Uses `CASCADE` where needed
|
|
369
|
-
- Adds `BEGIN`/`COMMIT` transaction wrapper
|
|
370
|
-
- Marks complex changes with ⚠️ for manual review
|
|
371
|
-
- Provides comments explaining each change
|
|
434
|
+
---
|
|
372
435
|
|
|
373
|
-
|
|
436
|
+
## Programmatic API
|
|
374
437
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
438
|
+
```typescript
|
|
439
|
+
import { Client } from "pg";
|
|
440
|
+
import {
|
|
441
|
+
SqlFileWriter,
|
|
442
|
+
DdlExtractor,
|
|
443
|
+
compareDdl,
|
|
444
|
+
generateMigration,
|
|
445
|
+
JsonExporter,
|
|
446
|
+
DocsGenerator,
|
|
447
|
+
MigrationTracker,
|
|
448
|
+
SnapshotManager,
|
|
449
|
+
createPool,
|
|
450
|
+
ProgressBar,
|
|
451
|
+
} from "@toichubek/pg-ddl-extractor";
|
|
452
|
+
|
|
453
|
+
// Extract DDL
|
|
454
|
+
const client = new Client({ /* config */ });
|
|
455
|
+
await client.connect();
|
|
456
|
+
|
|
457
|
+
const writer = new SqlFileWriter("./sql/dev");
|
|
458
|
+
const extractor = new DdlExtractor(client, writer);
|
|
459
|
+
await extractor.extractAll();
|
|
380
460
|
|
|
381
|
-
|
|
461
|
+
// Export as JSON
|
|
462
|
+
const jsonExporter = new JsonExporter(client);
|
|
463
|
+
const schema = await jsonExporter.export();
|
|
464
|
+
|
|
465
|
+
// Compare environments
|
|
466
|
+
const summary = compareDdl("./sql");
|
|
467
|
+
|
|
468
|
+
// Generate migration
|
|
469
|
+
const migration = generateMigration("./sql");
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## Migration Workflow
|
|
382
475
|
|
|
383
476
|
```bash
|
|
384
|
-
# 1.
|
|
385
|
-
|
|
477
|
+
# 1. Extract both environments
|
|
478
|
+
pg-ddl-extract --env dev
|
|
479
|
+
pg-ddl-extract --env prod
|
|
480
|
+
|
|
481
|
+
# 2. Compare
|
|
482
|
+
pg-ddl-diff --report
|
|
386
483
|
|
|
387
|
-
#
|
|
388
|
-
|
|
484
|
+
# 3. Generate migration with rollback
|
|
485
|
+
pg-ddl-migrate --with-rollback
|
|
389
486
|
|
|
390
|
-
#
|
|
391
|
-
|
|
392
|
-
pg-ddl-extract --help
|
|
487
|
+
# 4. Review generated files
|
|
488
|
+
cat sql/migrations/YYYYMMDD_HHmmss_dev_to_prod.sql
|
|
393
489
|
|
|
394
|
-
#
|
|
395
|
-
|
|
490
|
+
# 5. Test on staging, then apply
|
|
491
|
+
psql -d your_db -f sql/migrations/YYYYMMDD_HHmmss_dev_to_prod.sql
|
|
396
492
|
|
|
397
|
-
#
|
|
398
|
-
|
|
493
|
+
# 6. If something goes wrong
|
|
494
|
+
psql -d your_db -f sql/migrations/YYYYMMDD_HHmmss_rollback.sql
|
|
399
495
|
```
|
|
400
496
|
|
|
401
|
-
|
|
497
|
+
### Migration Safety
|
|
498
|
+
|
|
499
|
+
- Uses `IF EXISTS` for DROP commands
|
|
500
|
+
- Uses `CASCADE` where needed
|
|
501
|
+
- `BEGIN`/`COMMIT` transaction wrapper
|
|
502
|
+
- Complex changes marked with warnings for manual review
|
|
503
|
+
- Track history with `--track` flag
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## CI/CD Integration
|
|
402
508
|
|
|
403
509
|
```bash
|
|
404
|
-
#
|
|
405
|
-
|
|
510
|
+
# In your CI pipeline
|
|
511
|
+
pg-ddl-lint --env dev # Fail on schema errors
|
|
512
|
+
pg-ddl-validate --env dev --strict # Fail on warnings too
|
|
513
|
+
pg-ddl-extract --env dev # Snapshot schema
|
|
514
|
+
pg-ddl-diff # Check for drift
|
|
515
|
+
```
|
|
406
516
|
|
|
407
|
-
|
|
408
|
-
npm run build
|
|
517
|
+
## Git Workflow
|
|
409
518
|
|
|
410
|
-
|
|
411
|
-
|
|
519
|
+
```bash
|
|
520
|
+
pg-ddl-extract --env dev
|
|
521
|
+
git add sql/
|
|
522
|
+
git commit -m "chore: update database DDL snapshot"
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
## npm Scripts (local install / from source)
|
|
526
|
+
|
|
527
|
+
```bash
|
|
528
|
+
npm run extract:dev # Extract DEV
|
|
529
|
+
npm run extract:prod # Extract PROD
|
|
530
|
+
npm run diff # Compare
|
|
531
|
+
npm run diff:report # Compare + save reports
|
|
532
|
+
npm run migrate # Generate migration
|
|
533
|
+
npm run migrate:rollback # Migration + rollback
|
|
534
|
+
npm run migrate:dry-run # Preview
|
|
535
|
+
npm run schema:lint # Lint schema
|
|
536
|
+
npm run watch:dev # Watch DEV
|
|
537
|
+
npm run docs # Generate docs
|
|
538
|
+
npm run stats # DB statistics
|
|
412
539
|
```
|
|
413
540
|
|
|
414
541
|
## Tips
|
|
415
542
|
|
|
416
543
|
- Run before each release to capture DB changes
|
|
417
|
-
- Use `git diff sql/` to review structural changes
|
|
418
|
-
- The `_full_dump.sql` can
|
|
544
|
+
- Use `git diff sql/` to review structural changes
|
|
545
|
+
- The `_full_dump.sql` can recreate the schema from scratch
|
|
419
546
|
- Use a **readonly** database user for PROD extraction
|
|
420
547
|
- Add to CI/CD to auto-snapshot on deploy
|
|
421
|
-
- Generate migration plan
|
|
422
|
-
- Keep migration files in version control for audit trail
|
|
548
|
+
- Generate migration plan before each production deployment
|
|
549
|
+
- Keep migration files in version control for audit trail
|