[IMP] models._auto_init: avoid writing `False` default for boolean fields

Boolean fields always default to False in 8.0,
even when they do not have explicit default values.
This causes extra queries in the form:
  UPDATE <table> SET <bool_field> = false
      WHERE <bool_field> IS NULL;

Those are not necessary as the ORM automatically
folds NULL booleans to False, and can be very
expensive on tables with several million rows,
as the whole table may sometimes need to be
rewritten (can take dozens of minutes)
This commit is contained in:
Olivier Dony 2014-08-11 11:11:03 +02:00
parent 765beaa0c9
commit f28be81bc7
1 changed files with 9 additions and 4 deletions

View File

@ -2424,14 +2424,19 @@ class BaseModel(object):
if column_name in defaults:
default = field.convert_to_write(defaults[column_name])
ss = self._columns[column_name]._symbol_set
store_default = ss[1](default)
if store_default is not None:
column = self._columns[column_name]
ss = column._symbol_set
db_default = ss[1](default)
# Write default if non-NULL, except for booleans for which False means
# the same as NULL - this saves us an expensive query on large tables.
write_default = (db_default is not None if column._type != 'boolean'
else db_default)
if write_default:
_logger.debug("Table '%s': setting default value of new column %s to %r",
self._table, column_name, default)
query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (
self._table, column_name, ss[0], column_name)
cr.execute(query, (store_default,))
cr.execute(query, (db_default,))
# this is a disgrace
cr.commit()