[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:
parent
765beaa0c9
commit
f28be81bc7
|
@ -2424,14 +2424,19 @@ class BaseModel(object):
|
||||||
if column_name in defaults:
|
if column_name in defaults:
|
||||||
default = field.convert_to_write(defaults[column_name])
|
default = field.convert_to_write(defaults[column_name])
|
||||||
|
|
||||||
ss = self._columns[column_name]._symbol_set
|
column = self._columns[column_name]
|
||||||
store_default = ss[1](default)
|
ss = column._symbol_set
|
||||||
if store_default is not None:
|
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",
|
_logger.debug("Table '%s': setting default value of new column %s to %r",
|
||||||
self._table, column_name, default)
|
self._table, column_name, default)
|
||||||
query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (
|
query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (
|
||||||
self._table, column_name, ss[0], column_name)
|
self._table, column_name, ss[0], column_name)
|
||||||
cr.execute(query, (store_default,))
|
cr.execute(query, (db_default,))
|
||||||
# this is a disgrace
|
# this is a disgrace
|
||||||
cr.commit()
|
cr.commit()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue