pgdevkit 0.2.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

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.
@@ -75,6 +75,8 @@ def _testdb_env():
75
75
 
76
76
  `ensure_testdb()` starts the shared `pgdevkit-postgres` container if needed (via `podman`), creates a database scoped to this project+branch (so different worktrees/branches never collide), and applies every `.sql` file under `database_dir` in dependency order, seeding any `.test_data.json` sidecar files.
77
77
 
78
+ **`migrations/` is never applied here, on purpose.** If the test schema is missing something, that's a sign the base `tables/`/`views`/... file has drifted behind a migration that was only ever run manually against a real database — fix the base file, don't add migration-replay to `apply_schema()` (tried once, reverted: a migration can't be judged "safe to re-run" from its SQL text alone — see `docs/database-layout.md`'s Migrations section).
79
+
78
80
  | What do you need? | Command |
79
81
  |---|---|
80
82
  | First-time setup / apply new files | `pgdb testdb up` |
pgdevkit/testdb/schema.py CHANGED
@@ -172,54 +172,19 @@ async def _insert_test_data(
172
172
  await cur.executemany(insert_sql, rows)
173
173
 
174
174
 
175
- _UNSAFE_MIGRATION_PATTERNS = (
176
- "DROP COLUMN",
177
- "DROP TABLE",
178
- "TRUNCATE",
179
- "RENAME COLUMN",
180
- "RENAME TO",
181
- "DELETE FROM",
182
- "OWNER TO",
183
- )
184
-
185
-
186
- def _is_additive_migration(sql: str) -> bool:
187
- """Only pure-additive migrations (ADD COLUMN/CREATE ... IF NOT EXISTS,
188
- etc.) are safe to (re-)apply against a schema that already reflects
189
- later migrations — skip anything that could drop, rename, truncate, or
190
- delete existing structure/data, alter an existing column, or change
191
- ownership. This is a substring heuristic, not a SQL parser, so it errs
192
- towards skipping (a false negative here means real data loss replayed
193
- on every apply_schema() call) rather than trying to be exhaustive."""
194
- normalized = sql.upper()
195
- has_alter_column = "ALTER COLUMN" in normalized and "ADD COLUMN" not in normalized
196
- has_unsafe_pattern = any(pattern in normalized for pattern in _UNSAFE_MIGRATION_PATTERNS)
197
- return not (has_alter_column or has_unsafe_pattern)
198
-
199
-
200
- def _iter_migration_files(database_dir: Path):
201
- """Yield every `*.sql` file in any `migrations/` subdirectory, in
202
- filename order (the project's naming convention — numeric or date
203
- prefixes — sorts chronologically)."""
204
- for root, _, files in os.walk(database_dir):
205
- if Path(root).name != "migrations":
206
- continue
207
- for file in sorted(files):
208
- if file.endswith(".sql"):
209
- yield Path(root) / file
210
-
211
-
212
175
  async def apply_schema(
213
176
  con: psycopg.AsyncConnection,
214
177
  database_dir: Path,
215
178
  extensions: tuple[str, ...] = (),
216
179
  force_reset: bool = False,
217
180
  ) -> None:
218
- """Apply every .sql file under database_dir (in dependency-safe order),
219
- seed any matching .test_data.json files, then apply purely-additive
220
- `migrations/*.sql` files (see `_is_additive_migration`) so a schema that
221
- ships changes via migration files rather than editing the base object
222
- files stays in sync. Safe to call repeatedly."""
181
+ """Apply every .sql file under database_dir (in dependency-safe order)
182
+ and seed any matching .test_data.json files. Safe to call repeatedly.
183
+
184
+ `migrations/` subdirectories are never applied here — they're for
185
+ one-time manual application against real (already-provisioned)
186
+ databases, not for building a fresh schema. The base object files under
187
+ `database_dir` must reflect the current, final schema on their own."""
223
188
  await con.set_autocommit(True)
224
189
  for extension in extensions:
225
190
  await con.execute(SQL("CREATE EXTENSION IF NOT EXISTS {e}").format(e=Identifier(extension)))
@@ -243,13 +208,3 @@ async def apply_schema(
243
208
 
244
209
  for file, sql in failures:
245
210
  await _apply(file, sql)
246
-
247
- for migration_file in _iter_migration_files(database_dir):
248
- content = migration_file.read_text(encoding="utf-8")
249
- if not _is_additive_migration(content):
250
- continue
251
- try:
252
- await con.execute(cast(Any, content))
253
- logger.info("Applied migration %s", migration_file.name)
254
- except Exception as e: # noqa: BLE001
255
- logger.debug("Migration %s skipped (likely already applied): %s", migration_file.name, e)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pgdevkit
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: A helper for developing with Postgres
5
5
  Requires-Python: >=3.14
6
6
  Requires-Dist: psycopg[binary]>=3.2.0
@@ -20,12 +20,12 @@ pgdevkit/testdb/constants.py,sha256=xi8uIoEgN9LrRkr41j3mmWB9PqqU0r8aCUb2JJXBAs0,
20
20
  pgdevkit/testdb/container.py,sha256=24zl2_0mX24RTa2NCxps8RlJQAzdAif15TWgoVjNtMc,2974
21
21
  pgdevkit/testdb/naming.py,sha256=Kyk5qEfxUkbggUG5bD7U7CJ_kAET332VPQNB-O5kvTY,1318
22
22
  pgdevkit/testdb/query.py,sha256=e4UbgdCKKIot3a8Qixg-OX-Af0rlQ4a8ODhJBD8mtVM,2318
23
- pgdevkit/testdb/schema.py,sha256=99Wnl2JAD_kd5226uCAAHEcd_fl23D-kNYmt16asRgM,9573
23
+ pgdevkit/testdb/schema.py,sha256=Pz5wWiDz9sNyCe-VK_au7A-saTXzTGKVIorGFrbyV5I,7730
24
24
  pgdevkit/docs/database-layout.md,sha256=dNvDH956xSXuAnLqkOopyOfaIm_A-RtUd57VTaZ1GQU,6035
25
- pgdevkit/skills/pgdevkit/SKILL.md,sha256=anvsNNeC1-ixUk70L9owyQlQtN6_wUhykOGqU3mAboY,11524
25
+ pgdevkit/skills/pgdevkit/SKILL.md,sha256=CJS3LC5x8tjb6mJc8q_XQCknOwUd5LGSof3hteLsH2Y,11975
26
26
  pgdevkit/skills/pgdevkit/references/dynamic-sql.md,sha256=aTR1sx81moiTwaMaiOecaqk-9rT8y5Zxz7W1BoC3vK0,2774
27
27
  pgdevkit/skills/pgdevkit/references/temporal-tables.md,sha256=LwZnItvQWI7bB0oRHxIfUc0ynnq7N0V5Mnv-QHvFN3Q,1364
28
- pgdevkit-0.2.0.dist-info/METADATA,sha256=1KBvcghDMMHNmZ-IOBKawFnsdDiD2797b4dQZwX2mlg,5651
29
- pgdevkit-0.2.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
30
- pgdevkit-0.2.0.dist-info/entry_points.txt,sha256=FK2P55lf0WaGlOZJIINOGgCt8WB7ep0OnPsgnrp80bg,42
31
- pgdevkit-0.2.0.dist-info/RECORD,,
28
+ pgdevkit-0.2.1.dist-info/METADATA,sha256=VFDuRtm67C2UT4kl2QffVrwL0RNuC2U4ySUFU0st8I0,5651
29
+ pgdevkit-0.2.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
30
+ pgdevkit-0.2.1.dist-info/entry_points.txt,sha256=FK2P55lf0WaGlOZJIINOGgCt8WB7ep0OnPsgnrp80bg,42
31
+ pgdevkit-0.2.1.dist-info/RECORD,,