Migrations: relax session sql_mode so the chain runs on strict MySQL 8
Some checks failed
CI / backend (push) Successful in 1m38s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 7s
CI / migrations-mysql (push) Failing after 8s

Found by test-deploying on a Windows + MySQL 8.0 VM: migration 7a01 seeds the
canonical relationship types with a raw INSERT that omits the NOT-NULL
createddate/modifieddate columns (the ORM supplies those via Python defaults at
runtime, but a raw migration INSERT does not). MySQL 5.x's lax default sql_mode
accepted it; strict MySQL 8 rejects it with 1364 "Field 'createddate' doesn't
have a default value", so a fresh `flask db upgrade` died at 7a01. Dev runs
MySQL 5.6, so this never surfaced locally.

migrations/env.py now sets the migration session sql_mode to
NO_ENGINE_SUBSTITUTION (dropping STRICT_TRANS_TABLES) for the migration run
only - the app's own runtime connections keep their mode. Makes the whole chain
portable across MySQL versions. Guarded for non-MySQL (sqlite tests).

68 migration/smoke tests pass; fresh upgrade to head verified on MySQL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-13 13:06:07 -04:00
parent 83a4867d1b
commit 35690bd169

View File

@@ -139,6 +139,20 @@ def run_migrations_online():
pass
with connectable.connect() as connection:
# Relax the session sql_mode for the migration run. Some historical
# migrations seed reference rows with raw INSERTs that omit NOT-NULL
# timestamp columns (the ORM supplies those via Python defaults at
# runtime, but a raw migration INSERT does not). MySQL 5.x's lax default
# accepted that; strict MySQL 8 rejects it with 1364 "Field 'createddate'
# doesn't have a default value". Dropping STRICT_TRANS_TABLES for the
# migration session only (the app's own connections keep their mode)
# makes the chain portable across MySQL versions.
try:
connection.exec_driver_sql(
"SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION'")
except Exception:
pass # non-MySQL backends (e.g. sqlite in tests)
context.configure(
connection=connection,
target_metadata=get_metadata(),