Browse Source

[RFR] Group models per table when detecting columns to purge

to prevent problems with models sharing the same table
pull/95/head
Stefan Rijnhart 11 years ago
parent
commit
05b5c7a569
  1. 32
      database_cleanup/model/purge_columns.py

32
database_cleanup/model/purge_columns.py

@ -85,18 +85,21 @@ class CleanupPurgeWizardColumn(orm.TransientModel):
res['name'] = _('Purge columns') res['name'] = _('Purge columns')
return res return res
def get_orphaned_columns(self, cr, uid, model_pool, context=None):
def get_orphaned_columns(self, cr, uid, model_pools, context=None):
""" """
From openobject-server/openerp/osv/orm.py From openobject-server/openerp/osv/orm.py
Iterate on the database columns to identify columns Iterate on the database columns to identify columns
of fields which have been removed of fields which have been removed
""" """
columns = [
c for c in model_pool._columns
if not (isinstance(model_pool._columns[c], fields.function)
and not model_pool._columns[c].store)]
columns = list(set([
column for model_pool in model_pools
for column in model_pool._columns
if not (isinstance(model_pool._columns[column], fields.function)
and not model_pool._columns[column].store)
]))
columns += orm.MAGIC_COLUMNS columns += orm.MAGIC_COLUMNS
columns += self.blacklist.get(model_pool._table, [])
columns += self.blacklist.get(model_pools[0]._table, [])
cr.execute("SELECT a.attname" cr.execute("SELECT a.attname"
" FROM pg_class c, pg_attribute a" " FROM pg_class c, pg_attribute a"
@ -106,26 +109,37 @@ class CleanupPurgeWizardColumn(orm.TransientModel):
" AND pg_catalog.format_type(a.atttypid, a.atttypmod)" " AND pg_catalog.format_type(a.atttypid, a.atttypmod)"
" NOT IN ('cid', 'tid', 'oid', 'xid')" " NOT IN ('cid', 'tid', 'oid', 'xid')"
" AND a.attname NOT IN %s", " AND a.attname NOT IN %s",
(model_pool._table, False, tuple(columns))),
(model_pools[0]._table, False, tuple(columns))),
return [column[0] for column in cr.fetchall()] return [column[0] for column in cr.fetchall()]
def find(self, cr, uid, context=None): def find(self, cr, uid, context=None):
""" """
Search for columns that are not in the corresponding model. Search for columns that are not in the corresponding model.
Group models by table to prevent false positives for columns
that are only in some of the models sharing the same table.
Example of this is 'sale_id' not being a field of stock.picking.in
""" """
res = [] res = []
model_pool = self.pool['ir.model'] model_pool = self.pool['ir.model']
model_ids = model_pool.search(cr, uid, [], context=context) model_ids = model_pool.search(cr, uid, [], context=context)
line_pool = self.pool['cleanup.purge.line.column'] line_pool = self.pool['cleanup.purge.line.column']
# mapping of tables to tuples (model id, [pool1, pool2, ...])
table2model = {}
for model in model_pool.browse(cr, uid, model_ids, context=context): for model in model_pool.browse(cr, uid, model_ids, context=context):
model_pool = self.pool.get(model.model) model_pool = self.pool.get(model.model)
if not model_pool or not model_pool._auto: if not model_pool or not model_pool._auto:
continue continue
table2model.setdefault(model_pool._table, (model.id, []))[1].append(model_pool)
for table, model_spec in table2model.iteritems():
for column in self.get_orphaned_columns( for column in self.get_orphaned_columns(
cr, uid, model_pool, context=context):
cr, uid, model_spec[1], context=context):
res.append((0, 0, { res.append((0, 0, {
'name': column, 'name': column,
'model_id': model.id}))
'model_id': model_spec[0]}))
if not res: if not res:
raise orm.except_orm( raise orm.except_orm(
_('Nothing to do'), _('Nothing to do'),

Loading…
Cancel
Save