refactor: migrate _sql_constraints to models.Constraint (Odoo 19)#215
refactor: migrate _sql_constraints to models.Constraint (Odoo 19)#215kneckinator wants to merge 1 commit into
Conversation
Odoo 19 removed the _sql_constraints list-of-tuples in favor of models.Constraint class attributes. Migrate the three remaining sites (spp_scoring, spp_metric, spp_analytics) and update the metric_category test to introspect constraints via _table_objects.
There was a problem hiding this comment.
Code Review
This pull request replaces legacy _sql_constraints lists with Odoo's newer models.Constraint objects across several models. A critical issue was identified in the test suite where the assertion for the unique constraint name will fail because Odoo 19 automatically prefixes constraint names with the table name. The reviewer suggested stripping this prefix in the test's set comprehension to ensure the assertion succeeds.
| """ | ||
| # Verify the SQL constraint is defined | ||
| constraints = {name for name, _, _ in self.env["spp.metric.category"]._sql_constraints} | ||
| constraints = {obj.name for obj in self.env["spp.metric.category"]._table_objects.values()} |
There was a problem hiding this comment.
In Odoo 19, SQL constraints defined via models.Constraint are automatically prefixed with the table name (e.g., spp_metric_category_code_unique). As a result, checking for the bare constraint name "code_unique" on line 34 will fail because obj.name contains the fully prefixed name. Stripping the table prefix from the constraint names in the set comprehension ensures the test passes.
| constraints = {obj.name for obj in self.env["spp.metric.category"]._table_objects.values()} | |
| constraints = {obj.name.removeprefix("spp_metric_category_") for obj in self.env["spp.metric.category"]._table_objects.values()} |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 19.0 #215 +/- ##
==========================================
+ Coverage 71.27% 71.56% +0.29%
==========================================
Files 976 979 +3
Lines 57736 58392 +656
==========================================
+ Hits 41150 41791 +641
- Misses 16586 16601 +15
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Summary
_sql_constraints = [(name, sql, message), ...]pattern; it's replaced bymodels.Constraint(sql, message)class attributes.spp_scoring,spp_metric,spp_analytics.spp_metric/tests/test_metric_category.pyto introspect constraints via_table_objectsinstead of_sql_constraints.Notes on DB constraint names
The new system auto-prefixes the constraint name as
{table}_{attr_name_without_underscore}:spp_scoring.scoring.invalid.value: attr_name_uniq→spp_scoring_invalid_value_name_uniq(matches the previous name exactly).spp_metric.metric.category: attr_code_unique→spp_metric_category_code_unique(previouslycode_unique— name changes, but follows the same migration pattern already in use acrossspp_consent,spp_drims,spp_cel_domain, etc.).spp_analytics.analytics.cache: attr_cache_key_unique→spp_analytics_cache_cache_key_unique(previouslycache_key_unique).The legacy (unprefixed) DB constraints on
spp_metric_categoryandspp_analytics_cachewon't be auto-dropped; if that's important for existing databases, a pre-init hook can be added in a follow-up.Test plan
pytest spp_metric/tests/test_metric_category.py— verifies the constraint is reported via_table_objectsspp_scoring,spp_metric,spp_analytics