Overview
In Odoo 19, there are cases where a newly declared field in a Python model does not result in a corresponding column in PostgreSQL.
Typical scenario:
- Field is defined in a model (models.Model).
- Module is upgraded.
- No error is shown.
- Column is missing in the actual database table.
- Accessing the field triggers psycopg2.errors.UndefinedColumn.
This indicates ORM database schema desynchronization.
Why This Happens?
Common causes:
- Module upgrade did not run properly (-u module_name skipped or failed silently).
- Migration issue during ALTER TABLE.
- Column previously existed with incompatible type.
- Manual database modification in earlier development cycle.
- Interrupted server restart during schema update.
Odoo ORM normally generates ALTER TABLE automatically during module upgrade. When it fails or skips execution, the Python layer and database layer become inconsistent.
Scenario Example
Model extension:
from odoo import fields, models
class ResCompany(models.Model):
_inherit = 'res.company'
tax_limit = fields.Float(string='Tax Limit')
You inherit res.company and add a new stored Float field.
By default, Float is stored (store=True implicitly).
Expected behavior after module upgrade:
- Column tax_limit is created in table res_company.
- PostgreSQL type should be double precision.
If the module upgrade fails silently, the Python layer knows tax_limit, but the database table res_company does not contain the column.
1. Verifying the Issue in PostgreSQL
Inspect the table:
\d res_company
Or:
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'res_company'
AND column_name = 'tax_limit';
If no result is returned, the column was never created.
2. Manual Schema Alignment
If the column does not exist:
ALTER TABLE res_company
ADD COLUMN tax_limit double precision;
3. After Manual ALTER
Restart Odoo and upgrade the module:
./odoo-bin -u your_module -d your_database
Determine the Correct SQL Type
Common Odoo Field mappings:
Odoo Field | PostgreSQL Type |
Char | varchar |
Text | text |
Integer | integer |
Float | double precision |
Boolean | boolean |
Many2one | integer |
Monetary | numeric |
Date | data |
Datetime | timestamp |
