fix(change_request_v2): enforce reason-document uniqueness with models.Constraint - #395
Merged
Merged
Conversation
…s.Constraint (#394) The (cr_type_id, reason) rule on spp.cr.type.reason.document was declared via the legacy _sql_constraints attribute, which Odoo 19 ignores — the registry only logs a warning and the constraint is never created, so duplicate rules could be saved silently since 19.0.3.0.0 (release 2026.07). Re-declare it as models.Constraint (same derived PG constraint name, spp_cr_type_reason_document_reason_uniq). A pre-migration removes duplicate rules first (keeping the lowest-id rule per pair, matching which rule _get_effective_required_document_ids() applied), because a failed ADD CONSTRAINT during upgrade is downgraded by Odoo to a schema warning and the constraint would silently stay missing.
Nothing in CI caught the legacy attribute — the repo is otherwise fully migrated to models.Constraint (76 usages), and this one holdout shipped unnoticed. Report any class-body _sql_constraints assignment as an error with the models.Constraint replacement hint.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 19.0 #395 +/- ##
=======================================
Coverage 70.17% 70.18%
=======================================
Files 205 205
Lines 17751 17756 +5
=======================================
+ Hits 12457 12462 +5
Misses 5294 5294
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
…#394) With three or more copies of the same (cr_type_id, reason), the logging join matched a duplicate against every lower-id copy, emitting repeated warning lines for one deletion. SELECT DISTINCT and order by id. Found while exercising the upgrade end-to-end in the local Docker image.
emjay0921
approved these changes
Aug 5, 2026
emjay0921
left a comment
Contributor
There was a problem hiding this comment.
LGTM — approve (author to merge).
Correct root-cause fix: _sql_constraints → models.Constraint, matching the pattern already used 74× across the repo. Verified points:
- Complete repo-wide — after this PR the only real
_sql_constraintsclass attribute left is the one removed here; the newodoo19.sql_constraintslint rule enforces it going forward and pre-commit passing green confirms zero holdouts. - Migration is careful —
pre-migrate.pydedups before ADD CONSTRAINT, keeps the lowest-id rule per (cr_type_id, reason) (matching_get_effective_required_document_ids()'s runtime behaviour), guards the pre-19.0.3.0.0 'table doesn't exist yet' case, and logs each removal — sidestepping Odoo's silent downgrade of a failed constraint-add. - Tests are solid — 5 TDD tests (constraint in pg_constraint, duplicate raw-INSERT raises IntegrityError via the savepoint+mute_logger pattern, different reasons/types allowed, legacy attribute gone).
- Full changelog/version discipline (HISTORY.md, README.rst, index.html, manifest 19.0.3.1.0 → .1.1); all 32 CI checks green incl. the module's 330-test suite.
Minor non-blocking note: the new lint rule's doc_link (docs/principles/odoo19-compatibility.md#sql-constraints) points at a doc that doesn't exist in the repo — but every existing rule in check_odoo19.py uses that same path, so it's a pre-existing convention, not introduced here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #394.
What
spp.cr.type.reason.documentdeclared its(cr_type_id, reason)uniqueness rule with the legacy_sql_constraintsattribute, which Odoo 19 ignores entirely — the registry logs "Model attribute '_sql_constraints' is no longer supported" on every load and the constraint is never created. Duplicate per-reason document rules could be saved silently since 19.0.3.0.0 (release 2026.07). Full analysis in #394.Changes
spp_change_request_v2(19.0.3.1.0→19.0.3.1.1):models.Constraint(same derived PG constraint name,spp_cr_type_reason_document_reason_uniq; no rename hazard since the legacy constraint never existed in any DB).migrations/19.0.3.1.1/pre-migrate.py: deduplicate existing rules before the constraint applies — keeps the lowest-id rule per(cr_type_id, reason)(matching which rule_get_effective_required_document_ids()used at runtime) and logs each removal. Required because Odoo downgrades a failedADD CONSTRAINTduring upgrade to a schema warning, which would leave the constraint silently missing exactly on the databases that have duplicates.test_reason_document_constraint.py, following thespp_programs/tests/test_sql_constraints.pypattern): constraint exists inpg_constraint, duplicate insert raisesIntegrityError, different reasons / different types still allowed, legacy attribute is gone. Written first, TDD: 3 of 5 failed on the unfixed code.scripts/lint/check_odoo19.py: newodoo19.sql_constraintserror flagging any class-body_sql_constraintsassignment with themodels.Constraintreplacement hint — nothing in CI caught this holdout (the repo is otherwise fully migrated, 76models.Constraintusages).Verification
./spp t spp_change_request_v2: 0 failed, 0 error(s) of 330 tests; the registry_sql_constraintswarning no longer appears in the log.3 failed, 0 error(s) of 5 tests— proving the constraint was absent and duplicates were accepted.ADD CONSTRAINTthen succeeds.change_request_type.py:604reported as error) and to pass on the fixed file;./spp lint,ruff,ruff-formatclean on changed files.