pg-schema-diff 0.2.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Asad Shah
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,225 @@
1
+ Metadata-Version: 2.4
2
+ Name: pg-schema-diff
3
+ Version: 0.2.0
4
+ Summary: CLI tool to detect schema drift between PostgreSQL databases and generate safe migration SQL
5
+ Author-email: Asad Shah <asadshah7950@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Asadshah7950/schemadrift
8
+ Project-URL: Repository, https://github.com/Asadshah7950/schemadrift
9
+ Project-URL: Bug Tracker, https://github.com/Asadshah7950/schemadrift/issues
10
+ Keywords: postgresql,schema,migration,diff,database,devops
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Database
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: psycopg2-binary>=2.9.9
26
+ Requires-Dist: click>=8.1.7
27
+ Requires-Dist: rich>=13.7.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
31
+ Requires-Dist: pytest-mock>=3.14.0; extra == "dev"
32
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
33
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # schemadrift
37
+
38
+ > **Detect schema drift between PostgreSQL databases and generate safe, ordered migration SQL — from the command line.**
39
+
40
+ [![CI](https://github.com/Asadshah7950/schemadrift/actions/workflows/ci.yml/badge.svg)](https://github.com/Asadshah7950/schemadrift/actions/workflows/ci.yml)
41
+ [![PyPI version](https://img.shields.io/pypi/v/schemadrift.svg)](https://pypi.org/project/schemadrift/)
42
+ [![Python versions](https://img.shields.io/pypi/pyversions/schemadrift.svg)](https://pypi.org/project/schemadrift/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
44
+
45
+ ---
46
+
47
+ ## Features
48
+
49
+ - 🔍 **Schema inspection** — Introspects live PostgreSQL databases via `psycopg2` (tables, columns, indexes, foreign keys, enums)
50
+ - 🔄 **Drift detection** — Pure-Python diff engine with zero database dependency for the comparison step
51
+ - 📝 **Safe SQL generation** — Produces `BEGIN`/`COMMIT`-wrapped migration scripts in the correct dependency order (drop FKs first, create tables before adding columns, etc.)
52
+ - 🖥️ **Rich CLI** — Beautiful terminal output powered by [Rich](https://github.com/Textualize/rich)
53
+ - 📦 **Multiple output formats** — SQL, JSON, or human-readable summary
54
+ - ✅ **95%+ unit test coverage** — All core logic tested without a live database
55
+
56
+ ---
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install schemadrift
62
+ ```
63
+
64
+ Or install from source:
65
+
66
+ ```bash
67
+ git clone https://github.com/Asadshah7950/schemadrift.git
68
+ cd schemadrift
69
+ pip install -e '.[dev]'
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Quick Start
75
+
76
+ ### Python API
77
+
78
+ ```python
79
+ from schemadrift.inspector import SchemaInspector
80
+ from schemadrift.differ import SchemaDiffer
81
+ from schemadrift.generator import MigrationGenerator
82
+
83
+ # Introspect both databases
84
+ source = SchemaInspector("postgres://user:pass@source-host/mydb").snapshot()
85
+ target = SchemaInspector("postgres://user:pass@target-host/mydb").snapshot()
86
+
87
+ # Compute the diff
88
+ diff = SchemaDiffer(source, target).diff()
89
+
90
+ # Generate migration SQL
91
+ sql = MigrationGenerator(diff).generate()
92
+ print(sql)
93
+ ```
94
+
95
+ ### Output example
96
+
97
+ ```sql
98
+ BEGIN;
99
+
100
+ -- Drop foreign key: fk_orders_user
101
+ ALTER TABLE "orders" DROP CONSTRAINT "fk_orders_user";
102
+
103
+ -- Add table: payments
104
+ CREATE TABLE "payments" (
105
+ "id" integer NOT NULL,
106
+ "amount" numeric NOT NULL,
107
+ PRIMARY KEY ("id")
108
+ );
109
+
110
+ -- Add column: users.phone
111
+ ALTER TABLE "users" ADD COLUMN "phone" text;
112
+
113
+ -- Add foreign key: fk_orders_user
114
+ ALTER TABLE "orders" ADD CONSTRAINT "fk_orders_user"
115
+ FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION;
116
+
117
+ COMMIT;
118
+ ```
119
+
120
+ ---
121
+
122
+ ## CLI Usage
123
+
124
+ ### `diff` — Compare two schemas
125
+
126
+ ```bash
127
+ # Print migration SQL to stdout
128
+ schemadrift diff \
129
+ --source "postgres://user:pass@source-host/db" \
130
+ --target "postgres://user:pass@target-host/db"
131
+
132
+ # Save to a file
133
+ schemadrift diff \
134
+ --source "postgres://user:pass@source-host/db" \
135
+ --target "postgres://user:pass@target-host/db" \
136
+ --output migration.sql
137
+
138
+ # JSON output
139
+ schemadrift diff \
140
+ --source "postgres://user:pass@source-host/db" \
141
+ --target "postgres://user:pass@target-host/db" \
142
+ --format json
143
+
144
+ # Human-readable summary
145
+ schemadrift diff \
146
+ --source "postgres://user:pass@source-host/db" \
147
+ --target "postgres://user:pass@target-host/db" \
148
+ --format summary
149
+
150
+ # GitHub Actions / PR Markdown report
151
+ schemadrift diff \
152
+ --source "postgres://user:pass@source-host/db" \
153
+ --target "postgres://user:pass@target-host/db" \
154
+ --format markdown >> $GITHUB_STEP_SUMMARY
155
+
156
+ # CI/CD Gate: Fail pipeline (exit code 1) if schema drift is detected
157
+ schemadrift diff \
158
+ --source "postgres://user:pass@source-host/db" \
159
+ --target "postgres://user:pass@target-host/db" \
160
+ --fail-on-drift
161
+
162
+ # Rollback / down migration (revert target back to source)
163
+ schemadrift diff \
164
+ --source "postgres://user:pass@source-host/db" \
165
+ --target "postgres://user:pass@target-host/db" \
166
+ --direction down \
167
+ --output rollback.sql
168
+
169
+ # Non-transactional execution (omit BEGIN / COMMIT)
170
+ schemadrift diff \
171
+ --source "postgres://user:pass@source-host/db" \
172
+ --target "postgres://user:pass@target-host/db" \
173
+ --no-transaction
174
+
175
+ # Zero-downtime index management (CREATE / DROP INDEX CONCURRENTLY)
176
+ schemadrift diff \
177
+ --source "postgres://user:pass@source-host/db" \
178
+ --target "postgres://user:pass@target-host/db" \
179
+ --concurrently
180
+ ```
181
+
182
+
183
+ ### `inspect` — Print a schema overview
184
+
185
+ ```bash
186
+ schemadrift inspect --dsn "postgres://user:pass@host/db"
187
+ ```
188
+
189
+ Output:
190
+
191
+ ```
192
+ Schema Summary
193
+ ┌──────────────┬─────────┬─────────┐
194
+ │ Table │ Columns │ Indexes │
195
+ ├──────────────┼─────────┼─────────┤
196
+ │ orders │ 6 │ 3 │
197
+ │ payments │ 4 │ 1 │
198
+ │ users │ 8 │ 4 │
199
+ └──────────────┴─────────┴─────────┘
200
+ Foreign keys: 2
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Architecture
206
+
207
+ | Module | Description |
208
+ |---|---|
209
+ | [`schemadrift/models.py`](schemadrift/models.py) | Dataclasses for all schema objects (`ColumnDef`, `TableDef`, `IndexDef`, `ForeignKeyDef`, `SchemaSnapshot`, `DiffResult`) |
210
+ | [`schemadrift/inspector.py`](schemadrift/inspector.py) | `SchemaInspector` — connects to PostgreSQL and builds a `SchemaSnapshot` using `information_schema` and `pg_catalog` queries |
211
+ | [`schemadrift/differ.py`](schemadrift/differ.py) | `SchemaDiffer` — pure-Python comparison engine; no DB connection required |
212
+ | [`schemadrift/generator.py`](schemadrift/generator.py) | `MigrationGenerator` — converts a `DiffResult` into safe, ordered SQL wrapped in a transaction |
213
+ | [`schemadrift/cli.py`](schemadrift/cli.py) | Click CLI exposing `diff` and `inspect` commands with Rich terminal output |
214
+
215
+ ---
216
+
217
+ ## Contributing
218
+
219
+ Contributions, bug reports, and feature requests are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup instructions.
220
+
221
+ ---
222
+
223
+ ## License
224
+
225
+ [MIT](LICENSE) © 2024 Asad Shah
@@ -0,0 +1,190 @@
1
+ # schemadrift
2
+
3
+ > **Detect schema drift between PostgreSQL databases and generate safe, ordered migration SQL — from the command line.**
4
+
5
+ [![CI](https://github.com/Asadshah7950/schemadrift/actions/workflows/ci.yml/badge.svg)](https://github.com/Asadshah7950/schemadrift/actions/workflows/ci.yml)
6
+ [![PyPI version](https://img.shields.io/pypi/v/schemadrift.svg)](https://pypi.org/project/schemadrift/)
7
+ [![Python versions](https://img.shields.io/pypi/pyversions/schemadrift.svg)](https://pypi.org/project/schemadrift/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
9
+
10
+ ---
11
+
12
+ ## Features
13
+
14
+ - 🔍 **Schema inspection** — Introspects live PostgreSQL databases via `psycopg2` (tables, columns, indexes, foreign keys, enums)
15
+ - 🔄 **Drift detection** — Pure-Python diff engine with zero database dependency for the comparison step
16
+ - 📝 **Safe SQL generation** — Produces `BEGIN`/`COMMIT`-wrapped migration scripts in the correct dependency order (drop FKs first, create tables before adding columns, etc.)
17
+ - 🖥️ **Rich CLI** — Beautiful terminal output powered by [Rich](https://github.com/Textualize/rich)
18
+ - 📦 **Multiple output formats** — SQL, JSON, or human-readable summary
19
+ - ✅ **95%+ unit test coverage** — All core logic tested without a live database
20
+
21
+ ---
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install schemadrift
27
+ ```
28
+
29
+ Or install from source:
30
+
31
+ ```bash
32
+ git clone https://github.com/Asadshah7950/schemadrift.git
33
+ cd schemadrift
34
+ pip install -e '.[dev]'
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Quick Start
40
+
41
+ ### Python API
42
+
43
+ ```python
44
+ from schemadrift.inspector import SchemaInspector
45
+ from schemadrift.differ import SchemaDiffer
46
+ from schemadrift.generator import MigrationGenerator
47
+
48
+ # Introspect both databases
49
+ source = SchemaInspector("postgres://user:pass@source-host/mydb").snapshot()
50
+ target = SchemaInspector("postgres://user:pass@target-host/mydb").snapshot()
51
+
52
+ # Compute the diff
53
+ diff = SchemaDiffer(source, target).diff()
54
+
55
+ # Generate migration SQL
56
+ sql = MigrationGenerator(diff).generate()
57
+ print(sql)
58
+ ```
59
+
60
+ ### Output example
61
+
62
+ ```sql
63
+ BEGIN;
64
+
65
+ -- Drop foreign key: fk_orders_user
66
+ ALTER TABLE "orders" DROP CONSTRAINT "fk_orders_user";
67
+
68
+ -- Add table: payments
69
+ CREATE TABLE "payments" (
70
+ "id" integer NOT NULL,
71
+ "amount" numeric NOT NULL,
72
+ PRIMARY KEY ("id")
73
+ );
74
+
75
+ -- Add column: users.phone
76
+ ALTER TABLE "users" ADD COLUMN "phone" text;
77
+
78
+ -- Add foreign key: fk_orders_user
79
+ ALTER TABLE "orders" ADD CONSTRAINT "fk_orders_user"
80
+ FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION;
81
+
82
+ COMMIT;
83
+ ```
84
+
85
+ ---
86
+
87
+ ## CLI Usage
88
+
89
+ ### `diff` — Compare two schemas
90
+
91
+ ```bash
92
+ # Print migration SQL to stdout
93
+ schemadrift diff \
94
+ --source "postgres://user:pass@source-host/db" \
95
+ --target "postgres://user:pass@target-host/db"
96
+
97
+ # Save to a file
98
+ schemadrift diff \
99
+ --source "postgres://user:pass@source-host/db" \
100
+ --target "postgres://user:pass@target-host/db" \
101
+ --output migration.sql
102
+
103
+ # JSON output
104
+ schemadrift diff \
105
+ --source "postgres://user:pass@source-host/db" \
106
+ --target "postgres://user:pass@target-host/db" \
107
+ --format json
108
+
109
+ # Human-readable summary
110
+ schemadrift diff \
111
+ --source "postgres://user:pass@source-host/db" \
112
+ --target "postgres://user:pass@target-host/db" \
113
+ --format summary
114
+
115
+ # GitHub Actions / PR Markdown report
116
+ schemadrift diff \
117
+ --source "postgres://user:pass@source-host/db" \
118
+ --target "postgres://user:pass@target-host/db" \
119
+ --format markdown >> $GITHUB_STEP_SUMMARY
120
+
121
+ # CI/CD Gate: Fail pipeline (exit code 1) if schema drift is detected
122
+ schemadrift diff \
123
+ --source "postgres://user:pass@source-host/db" \
124
+ --target "postgres://user:pass@target-host/db" \
125
+ --fail-on-drift
126
+
127
+ # Rollback / down migration (revert target back to source)
128
+ schemadrift diff \
129
+ --source "postgres://user:pass@source-host/db" \
130
+ --target "postgres://user:pass@target-host/db" \
131
+ --direction down \
132
+ --output rollback.sql
133
+
134
+ # Non-transactional execution (omit BEGIN / COMMIT)
135
+ schemadrift diff \
136
+ --source "postgres://user:pass@source-host/db" \
137
+ --target "postgres://user:pass@target-host/db" \
138
+ --no-transaction
139
+
140
+ # Zero-downtime index management (CREATE / DROP INDEX CONCURRENTLY)
141
+ schemadrift diff \
142
+ --source "postgres://user:pass@source-host/db" \
143
+ --target "postgres://user:pass@target-host/db" \
144
+ --concurrently
145
+ ```
146
+
147
+
148
+ ### `inspect` — Print a schema overview
149
+
150
+ ```bash
151
+ schemadrift inspect --dsn "postgres://user:pass@host/db"
152
+ ```
153
+
154
+ Output:
155
+
156
+ ```
157
+ Schema Summary
158
+ ┌──────────────┬─────────┬─────────┐
159
+ │ Table │ Columns │ Indexes │
160
+ ├──────────────┼─────────┼─────────┤
161
+ │ orders │ 6 │ 3 │
162
+ │ payments │ 4 │ 1 │
163
+ │ users │ 8 │ 4 │
164
+ └──────────────┴─────────┴─────────┘
165
+ Foreign keys: 2
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Architecture
171
+
172
+ | Module | Description |
173
+ |---|---|
174
+ | [`schemadrift/models.py`](schemadrift/models.py) | Dataclasses for all schema objects (`ColumnDef`, `TableDef`, `IndexDef`, `ForeignKeyDef`, `SchemaSnapshot`, `DiffResult`) |
175
+ | [`schemadrift/inspector.py`](schemadrift/inspector.py) | `SchemaInspector` — connects to PostgreSQL and builds a `SchemaSnapshot` using `information_schema` and `pg_catalog` queries |
176
+ | [`schemadrift/differ.py`](schemadrift/differ.py) | `SchemaDiffer` — pure-Python comparison engine; no DB connection required |
177
+ | [`schemadrift/generator.py`](schemadrift/generator.py) | `MigrationGenerator` — converts a `DiffResult` into safe, ordered SQL wrapped in a transaction |
178
+ | [`schemadrift/cli.py`](schemadrift/cli.py) | Click CLI exposing `diff` and `inspect` commands with Rich terminal output |
179
+
180
+ ---
181
+
182
+ ## Contributing
183
+
184
+ Contributions, bug reports, and feature requests are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup instructions.
185
+
186
+ ---
187
+
188
+ ## License
189
+
190
+ [MIT](LICENSE) © 2024 Asad Shah
@@ -0,0 +1,225 @@
1
+ Metadata-Version: 2.4
2
+ Name: pg-schema-diff
3
+ Version: 0.2.0
4
+ Summary: CLI tool to detect schema drift between PostgreSQL databases and generate safe migration SQL
5
+ Author-email: Asad Shah <asadshah7950@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Asadshah7950/schemadrift
8
+ Project-URL: Repository, https://github.com/Asadshah7950/schemadrift
9
+ Project-URL: Bug Tracker, https://github.com/Asadshah7950/schemadrift/issues
10
+ Keywords: postgresql,schema,migration,diff,database,devops
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Database
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: psycopg2-binary>=2.9.9
26
+ Requires-Dist: click>=8.1.7
27
+ Requires-Dist: rich>=13.7.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
31
+ Requires-Dist: pytest-mock>=3.14.0; extra == "dev"
32
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
33
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # schemadrift
37
+
38
+ > **Detect schema drift between PostgreSQL databases and generate safe, ordered migration SQL — from the command line.**
39
+
40
+ [![CI](https://github.com/Asadshah7950/schemadrift/actions/workflows/ci.yml/badge.svg)](https://github.com/Asadshah7950/schemadrift/actions/workflows/ci.yml)
41
+ [![PyPI version](https://img.shields.io/pypi/v/schemadrift.svg)](https://pypi.org/project/schemadrift/)
42
+ [![Python versions](https://img.shields.io/pypi/pyversions/schemadrift.svg)](https://pypi.org/project/schemadrift/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
44
+
45
+ ---
46
+
47
+ ## Features
48
+
49
+ - 🔍 **Schema inspection** — Introspects live PostgreSQL databases via `psycopg2` (tables, columns, indexes, foreign keys, enums)
50
+ - 🔄 **Drift detection** — Pure-Python diff engine with zero database dependency for the comparison step
51
+ - 📝 **Safe SQL generation** — Produces `BEGIN`/`COMMIT`-wrapped migration scripts in the correct dependency order (drop FKs first, create tables before adding columns, etc.)
52
+ - 🖥️ **Rich CLI** — Beautiful terminal output powered by [Rich](https://github.com/Textualize/rich)
53
+ - 📦 **Multiple output formats** — SQL, JSON, or human-readable summary
54
+ - ✅ **95%+ unit test coverage** — All core logic tested without a live database
55
+
56
+ ---
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install schemadrift
62
+ ```
63
+
64
+ Or install from source:
65
+
66
+ ```bash
67
+ git clone https://github.com/Asadshah7950/schemadrift.git
68
+ cd schemadrift
69
+ pip install -e '.[dev]'
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Quick Start
75
+
76
+ ### Python API
77
+
78
+ ```python
79
+ from schemadrift.inspector import SchemaInspector
80
+ from schemadrift.differ import SchemaDiffer
81
+ from schemadrift.generator import MigrationGenerator
82
+
83
+ # Introspect both databases
84
+ source = SchemaInspector("postgres://user:pass@source-host/mydb").snapshot()
85
+ target = SchemaInspector("postgres://user:pass@target-host/mydb").snapshot()
86
+
87
+ # Compute the diff
88
+ diff = SchemaDiffer(source, target).diff()
89
+
90
+ # Generate migration SQL
91
+ sql = MigrationGenerator(diff).generate()
92
+ print(sql)
93
+ ```
94
+
95
+ ### Output example
96
+
97
+ ```sql
98
+ BEGIN;
99
+
100
+ -- Drop foreign key: fk_orders_user
101
+ ALTER TABLE "orders" DROP CONSTRAINT "fk_orders_user";
102
+
103
+ -- Add table: payments
104
+ CREATE TABLE "payments" (
105
+ "id" integer NOT NULL,
106
+ "amount" numeric NOT NULL,
107
+ PRIMARY KEY ("id")
108
+ );
109
+
110
+ -- Add column: users.phone
111
+ ALTER TABLE "users" ADD COLUMN "phone" text;
112
+
113
+ -- Add foreign key: fk_orders_user
114
+ ALTER TABLE "orders" ADD CONSTRAINT "fk_orders_user"
115
+ FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION;
116
+
117
+ COMMIT;
118
+ ```
119
+
120
+ ---
121
+
122
+ ## CLI Usage
123
+
124
+ ### `diff` — Compare two schemas
125
+
126
+ ```bash
127
+ # Print migration SQL to stdout
128
+ schemadrift diff \
129
+ --source "postgres://user:pass@source-host/db" \
130
+ --target "postgres://user:pass@target-host/db"
131
+
132
+ # Save to a file
133
+ schemadrift diff \
134
+ --source "postgres://user:pass@source-host/db" \
135
+ --target "postgres://user:pass@target-host/db" \
136
+ --output migration.sql
137
+
138
+ # JSON output
139
+ schemadrift diff \
140
+ --source "postgres://user:pass@source-host/db" \
141
+ --target "postgres://user:pass@target-host/db" \
142
+ --format json
143
+
144
+ # Human-readable summary
145
+ schemadrift diff \
146
+ --source "postgres://user:pass@source-host/db" \
147
+ --target "postgres://user:pass@target-host/db" \
148
+ --format summary
149
+
150
+ # GitHub Actions / PR Markdown report
151
+ schemadrift diff \
152
+ --source "postgres://user:pass@source-host/db" \
153
+ --target "postgres://user:pass@target-host/db" \
154
+ --format markdown >> $GITHUB_STEP_SUMMARY
155
+
156
+ # CI/CD Gate: Fail pipeline (exit code 1) if schema drift is detected
157
+ schemadrift diff \
158
+ --source "postgres://user:pass@source-host/db" \
159
+ --target "postgres://user:pass@target-host/db" \
160
+ --fail-on-drift
161
+
162
+ # Rollback / down migration (revert target back to source)
163
+ schemadrift diff \
164
+ --source "postgres://user:pass@source-host/db" \
165
+ --target "postgres://user:pass@target-host/db" \
166
+ --direction down \
167
+ --output rollback.sql
168
+
169
+ # Non-transactional execution (omit BEGIN / COMMIT)
170
+ schemadrift diff \
171
+ --source "postgres://user:pass@source-host/db" \
172
+ --target "postgres://user:pass@target-host/db" \
173
+ --no-transaction
174
+
175
+ # Zero-downtime index management (CREATE / DROP INDEX CONCURRENTLY)
176
+ schemadrift diff \
177
+ --source "postgres://user:pass@source-host/db" \
178
+ --target "postgres://user:pass@target-host/db" \
179
+ --concurrently
180
+ ```
181
+
182
+
183
+ ### `inspect` — Print a schema overview
184
+
185
+ ```bash
186
+ schemadrift inspect --dsn "postgres://user:pass@host/db"
187
+ ```
188
+
189
+ Output:
190
+
191
+ ```
192
+ Schema Summary
193
+ ┌──────────────┬─────────┬─────────┐
194
+ │ Table │ Columns │ Indexes │
195
+ ├──────────────┼─────────┼─────────┤
196
+ │ orders │ 6 │ 3 │
197
+ │ payments │ 4 │ 1 │
198
+ │ users │ 8 │ 4 │
199
+ └──────────────┴─────────┴─────────┘
200
+ Foreign keys: 2
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Architecture
206
+
207
+ | Module | Description |
208
+ |---|---|
209
+ | [`schemadrift/models.py`](schemadrift/models.py) | Dataclasses for all schema objects (`ColumnDef`, `TableDef`, `IndexDef`, `ForeignKeyDef`, `SchemaSnapshot`, `DiffResult`) |
210
+ | [`schemadrift/inspector.py`](schemadrift/inspector.py) | `SchemaInspector` — connects to PostgreSQL and builds a `SchemaSnapshot` using `information_schema` and `pg_catalog` queries |
211
+ | [`schemadrift/differ.py`](schemadrift/differ.py) | `SchemaDiffer` — pure-Python comparison engine; no DB connection required |
212
+ | [`schemadrift/generator.py`](schemadrift/generator.py) | `MigrationGenerator` — converts a `DiffResult` into safe, ordered SQL wrapped in a transaction |
213
+ | [`schemadrift/cli.py`](schemadrift/cli.py) | Click CLI exposing `diff` and `inspect` commands with Rich terminal output |
214
+
215
+ ---
216
+
217
+ ## Contributing
218
+
219
+ Contributions, bug reports, and feature requests are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup instructions.
220
+
221
+ ---
222
+
223
+ ## License
224
+
225
+ [MIT](LICENSE) © 2024 Asad Shah
@@ -0,0 +1,20 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ pg_schema_diff.egg-info/PKG-INFO
5
+ pg_schema_diff.egg-info/SOURCES.txt
6
+ pg_schema_diff.egg-info/dependency_links.txt
7
+ pg_schema_diff.egg-info/entry_points.txt
8
+ pg_schema_diff.egg-info/requires.txt
9
+ pg_schema_diff.egg-info/top_level.txt
10
+ schemadrift/__init__.py
11
+ schemadrift/cli.py
12
+ schemadrift/differ.py
13
+ schemadrift/generator.py
14
+ schemadrift/inspector.py
15
+ schemadrift/models.py
16
+ tests/test_cli.py
17
+ tests/test_differ.py
18
+ tests/test_generator.py
19
+ tests/test_inspector.py
20
+ tests/test_models.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ schemadrift = schemadrift.cli:main