v0.1.28 - Version bump and editor/throughput updates

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 22:51:29 +12:00
co-authored by Claude Opus 4.8
parent 3f8279af10
commit 1dd48bc771
10 changed files with 395 additions and 72 deletions
+61 -2
View File
@@ -66,9 +66,15 @@ class MigrationReport:
created_tables: tuple[str, ...] = ()
added_columns: tuple[str, ...] = ()
synced_tenant_rows: dict[str, int] = field(default_factory=dict)
resynced_sequences: tuple[str, ...] = ()
def has_changes(self) -> bool:
return bool(self.created_tables or self.added_columns or self.synced_tenant_rows)
return bool(
self.created_tables
or self.added_columns
or self.synced_tenant_rows
or self.resynced_sequences
)
def summary(self) -> str:
parts: list[str] = []
@@ -79,6 +85,8 @@ class MigrationReport:
if self.synced_tenant_rows:
counts = ", ".join(f"{table}={count}" for table, count in sorted(self.synced_tenant_rows.items()))
parts.append(f"synced tenant rows: {counts}")
if self.resynced_sequences:
parts.append(f"resynced sequences: {', '.join(self.resynced_sequences)}")
return "; ".join(parts) if parts else "schema already up to date"
@@ -435,7 +443,58 @@ def sync_product_visibility(engine: Engine) -> int:
return result.rowcount or 0
def resync_identity_sequences(engine: Engine) -> tuple[str, ...]:
"""Realign Postgres identity sequences with each table's current MAX(id).
After a bulk import that carries original primary keys across (the SQLite →
Postgres migration inserts rows with their existing ids), every table's
sequence still points at its starting value. The next INSERT then reuses an
id that already exists and fails with ``duplicate key value violates unique
constraint`` — which is why creating a new mix/ingredient/product saved fine
on SQLite but not on production Postgres.
This advances each ``id`` sequence to MAX(id) so the next INSERT continues
cleanly. It is a no-op on SQLite and idempotent on Postgres, so it is safe to
run on every startup. A per-table failure is skipped rather than aborting the
whole boot.
"""
if engine.dialect.name != "postgresql":
return ()
resynced: list[str] = []
inspector = inspect(engine)
with engine.begin() as connection:
for table_name in inspector.get_table_names():
if not any(column["name"] == "id" for column in inspector.get_columns(table_name)):
continue
try:
sequence = connection.execute(
text("SELECT pg_get_serial_sequence(:table, 'id')"),
{"table": table_name},
).scalar()
if not sequence:
continue
max_id = connection.execute(text(f'SELECT MAX(id) FROM "{table_name}"')).scalar()
if max_id is None:
continue
connection.execute(
text("SELECT setval(:sequence, :value, true)"),
{"sequence": sequence, "value": int(max_id)},
)
resynced.append(table_name)
except Exception:
# A single problematic table must not block startup; the others
# still get realigned.
continue
return tuple(resynced)
def bootstrap_schema(engine: Engine, metadata: MetaData) -> MigrationReport:
created_tables = ensure_metadata_tables(engine, metadata)
added_columns = ensure_tenant_columns(engine) + ensure_legacy_columns(engine)
return MigrationReport(created_tables=created_tables, added_columns=added_columns)
resynced_sequences = resync_identity_sequences(engine)
return MigrationReport(
created_tables=created_tables,
added_columns=added_columns,
resynced_sequences=resynced_sequences,
)