Clean ir.model and ir.model.field once every models have been registered

The same model can be registered multiple times by one module so the cleaning
can only happen when the all the classes have been registered.

issue7500
review53271002
This commit is contained in:
Cédric Krier committed 2018-06-11 23:18:28 +02:00
1 parent 65659dcf30
commit c244bdf422
2 files changed
+56 -3

No files matched your search

+46 -1
View File
@@ -1,8 +1,9 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import re
import heapq
import json
import logging
import re
from sql import Null
from sql.aggregate import Max
@@ -33,6 +34,7 @@ __all__ = [
'ModelData', 'PrintModelGraphStart', 'PrintModelGraph', 'ModelGraph',
'ModelWorkflowGraph',
]
logger = logging.getLogger(__name__)
class Model(ModelSQL, ModelView):
@@ -105,6 +107,26 @@ class Model(ModelSQL, ModelView):
where=ir_model.id == model_id))
return model_id
@classmethod
def clean(cls):
pool = Pool()
transaction = Transaction()
cursor = transaction.connection.cursor()
ir_model = cls.__table__()
cursor.execute(*ir_model.select(ir_model.model, ir_model.id))
for model, id_ in cursor:
try:
pool.get(model)
except KeyError:
logger.info("remove model: %s", model)
try:
cls.delete([cls(id_)])
transaction.commit()
except Exception:
transaction.rollback()
logger.error(
"could not delete model: %s", model, exc_info=True)
@classmethod
def list_models(cls):
'Return a list of all models names'
@@ -259,6 +281,29 @@ class ModelField(ModelSQL, ModelView):
where=ir_model_field.id ==
model_fields[field_name]['id']))
@classmethod
def clean(cls):
pool = Pool()
IrModel = pool.get('ir.model')
transaction = Transaction()
cursor = transaction.connection.cursor()
ir_model = IrModel.__table__()
ir_model_field = cls.__table__()
cursor.execute(*ir_model_field
.join(ir_model, condition=ir_model_field.model == ir_model.id)
.select(ir_model.model, ir_model_field.name, ir_model_field.id))
for model, field, id_ in cursor:
Model = pool.get(model)
if field not in Model._fields:
logger.info("remove field: %s.%s", model, field)
try:
cls.delete([cls(id_)])
transaction.commit()
except Exception:
transaction.rollback()
logger.error(
"could not delete field: %s.%s", model, field,
exc_info=True)
@staticmethod
def default_name():
+10 -2
View File
@@ -215,7 +215,8 @@ def load_module_graph(graph, pool, update=None, lang=None):
lang.add(code)
code = get_parent_language(code)
with Transaction().connection.cursor() as cursor:
transaction = Transaction()
with transaction.connection.cursor() as cursor:
modules = [x.name for x in graph]
cursor.execute(*ir_module.select(ir_module.name, ir_module.state,
where=ir_module.name.in_(modules)))
@@ -296,10 +297,17 @@ def load_module_graph(graph, pool, update=None, lang=None):
]))
module2state[package.name] = 'activated'
Transaction().connection.commit()
transaction.commit()
if not update:
pool.setup()
else:
# Remove unknown models and fields
Model = pool.get('ir.model')
Model.clean()
ModelField = pool.get('ir.model.field')
ModelField.clean()
transaction.commit()
pool.setup_mixin(modules)