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:
1 parent
65659dcf30
commit
c244bdf422
2 files changed
+56
-3
No files matched your search
+46
-1
@@ -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():
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in new issue
Block a user