Compare commits
1 Commits
feat/ldaps
...
fix/materi
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f280d4bd1 |
@@ -32,7 +32,11 @@ def upgrade() -> None:
|
||||
sa.Column('code', sa.String(length=80), nullable=False, server_default=''),
|
||||
sa.Column('description', sa.String(length=300), nullable=False, server_default=''),
|
||||
sa.Column('unit', sa.String(length=20), nullable=False, server_default=''),
|
||||
sa.Column('active', sa.Boolean(), nullable=False, server_default=sa.text('1')),
|
||||
# sa.true(), not sa.text('1'): SQLite coerces integer 1 to boolean,
|
||||
# Postgres refuses it (DatatypeMismatch) - found when this migration
|
||||
# took down the wp.controls.dev api container on 2026-08-21. The
|
||||
# location-taxonomy migration next door had it right all along.
|
||||
sa.Column('active', sa.Boolean(), nullable=False, server_default=sa.true()),
|
||||
sa.Column('sort', sa.Integer(), nullable=False, server_default='0'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
|
||||
@@ -54,6 +54,20 @@ def main():
|
||||
chk("locations and materials are both instances of it - not a copy beside it",
|
||||
"locList = WPListImport(" in suite and "matList = WPListImport(" in suite
|
||||
and "function locImport(dryRun){ locList.importText" in suite)
|
||||
# The 2026-08-21 outage, pinned: a Boolean server_default of sa.text('1')
|
||||
# passes on SQLite (which coerces 1) and crash-loops Postgres at deploy
|
||||
# (DatatypeMismatch). Every migration must say sa.true()/sa.false().
|
||||
import re as _re
|
||||
bad = []
|
||||
vdir = os.path.join(ROOT, "server", "alembic", "versions")
|
||||
for fn in sorted(os.listdir(vdir)):
|
||||
if not fn.endswith(".py"):
|
||||
continue
|
||||
for ln in open(os.path.join(vdir, fn), encoding="utf-8"):
|
||||
if "Boolean" in ln and "server_default" in ln and not _re.search(r"server_default=sa\.(true|false)\(\)", ln):
|
||||
bad.append("%s: %s" % (fn, ln.strip()[:90]))
|
||||
chk("no migration gives a Boolean a non-portable server_default "
|
||||
"(sa.true()/sa.false() only)", not bad, ascii_(bad[:3]))
|
||||
model = open(os.path.join(ROOT, "server", "models.py"), encoding="utf-8").read()
|
||||
mat_block = model[model.find("class MaterialItem"):model.find("class WpFile")]
|
||||
cols = re.findall(r"^\s+(\w+): Mapped", mat_block, re.M)
|
||||
|
||||
Reference in New Issue
Block a user