• odoo启动-加载模块(load_modules)


    odoo启动-加载模块(load_modules)

    odoo每次启动的时候都会加载模块,加载模块的过程就是调用load_modules 函数

    在函数位于 odoo\modules\loading.py

    代码中注释也写的很清楚,共分了9个步骤,其实是8个步骤。

    这个函数的作用是为一个新创建的注册表对象加载模块,这是Registry.new()的一部分,不应该用在其他地方。

    def load_modules(registry, force_demo=False, status=None, update_module=False):
        """ Load the modules for a registry object that has just been created.  This
            function is part of Registry.new() and should not be used anywhere else.
        """
        initialize_sys_path()
    
        force = []
        if force_demo:
            force.append('demo')
    
        models_to_check = set()
    
        with registry.cursor() as cr:
            # prevent endless wait for locks on schema changes (during online
            # installs) if a concurrent transaction has accessed the table;
            # connection settings are automatically reset when the connection is
            # borrowed from the pool
            cr.execute("SET SESSION lock_timeout = '15s'")
            if not odoo.modules.db.is_initialized(cr):
                if not update_module:
                    _logger.error("Database %s not initialized, you can force it with `-i base`", cr.dbname)
                    return
                _logger.info("init db")
                odoo.modules.db.initialize(cr)
                update_module = True # process auto-installed modules
                tools.config["init"]["all"] = 1
                if not tools.config['without_demo']:
                    tools.config["demo"]['all'] = 1
    
            if 'base' in tools.config['update'] or 'all' in tools.config['update']:
                cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed'))
    
            # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps)
            graph = odoo.modules.graph.Graph()
            graph.add_module(cr, 'base', force)
            if not graph:
                _logger.critical('module base cannot be loaded! (hint: verify addons-path)')
                raise ImportError('Module `base` cannot be loaded! (hint: verify addons-path)')
    
            if update_module and odoo.tools.table_exists(cr, 'ir_model_fields'):
                # determine the fields which are currently translated in the database
                cr.execute("SELECT model || '.' || name FROM ir_model_fields WHERE translate IS TRUE")
                registry._database_translated_fields = {row[0] for row in cr.fetchall()}
    
            # processed_modules: for cleanup step after install
            # loaded_modules: to avoid double loading
            report = registry._assertion_report
            loaded_modules, processed_modules = load_module_graph(
                cr, graph, status, perform_checks=update_module,
                report=report, models_to_check=models_to_check)
    
            load_lang = tools.config.pop('load_language')
            if load_lang or update_module:
                # some base models are used below, so make sure they are set up
                registry.setup_models(cr)
    
            if load_lang:
                for lang in load_lang.split(','):
                    tools.load_language(cr, lang)
    
            # STEP 2: Mark other modules to be loaded/updated
            if update_module:
                env = api.Environment(cr, SUPERUSER_ID, {})
                Module = env['ir.module.module']
                _logger.info('updating modules list')
                Module.update_list()
    
                _check_module_names(cr, itertools.chain(tools.config['init'], tools.config['update']))
    
                module_names = [k for k, v in tools.config['init'].items() if v]
                if module_names:
                    modules = Module.search([('state', '=', 'uninstalled'), ('name', 'in', module_names)])
                    if modules:
                        modules.button_install()
    
                module_names = [k for k, v in tools.config['update'].items() if v]
                if module_names:
                    modules = Module.search([('state', 'in', ('installed', 'to upgrade')), ('name', 'in', module_names)])
                    if modules:
                        modules.button_upgrade()
    
                env.flush_all()
                cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
                Module.invalidate_model(['state'])
    
            # STEP 3: Load marked modules (skipping base which was done in STEP 1)
            # IMPORTANT: this is done in two parts, first loading all installed or
            #            partially installed modules (i.e. installed/to upgrade), to
            #            offer a consistent system to the second part: installing
            #            newly selected modules.
            #            We include the modules 'to remove' in the first step, because
            #            they are part of the "currently installed" modules. They will
            #            be dropped in STEP 6 later, before restarting the loading
            #            process.
            # IMPORTANT 2: We have to loop here until all relevant modules have been
            #              processed, because in some rare cases the dependencies have
            #              changed, and modules that depend on an uninstalled module
            #              will not be processed on the first pass.
            #              It's especially useful for migrations.
            previously_processed = -1
            while previously_processed < len(processed_modules):
                previously_processed = len(processed_modules)
                processed_modules += load_marked_modules(cr, graph,
                    ['installed', 'to upgrade', 'to remove'],
                    force, status, report, loaded_modules, update_module, models_to_check)
                if update_module:
                    processed_modules += load_marked_modules(cr, graph,
                        ['to install'], force, status, report,
                        loaded_modules, update_module, models_to_check)
    
            if update_module:
                # set up the registry without the patch for translated fields
                database_translated_fields = registry._database_translated_fields
                registry._database_translated_fields = ()
                registry.setup_models(cr)
                # determine which translated fields should no longer be translated,
                # and make their model fix the database schema
                models_to_untranslate = set()
                for full_name in database_translated_fields:
                    model_name, field_name = full_name.rsplit('.', 1)
                    if model_name in registry:
                        field = registry[model_name]._fields.get(field_name)
                        if field and not field.translate:
                            _logger.debug("Making field %s non-translated", field)
                            models_to_untranslate.add(model_name)
                registry.init_models(cr, list(models_to_untranslate), {'models_to_check': True})
    
            registry.loaded = True
            registry.setup_models(cr)
    
            # check that all installed modules have been loaded by the registry
            env = api.Environment(cr, SUPERUSER_ID, {})
            Module = env['ir.module.module']
            modules = Module.search(Module._get_modules_to_load_domain(), order='name')
            missing = [name for name in modules.mapped('name') if name not in graph]
            if missing:
                _logger.error("Some modules are not loaded, some dependencies or manifest may be missing: %s", missing)
    
            # STEP 3.5: execute migration end-scripts
            migrations = odoo.modules.migration.MigrationManager(cr, graph)
            for package in graph:
                migrations.migrate_module(package, 'end')
    
            # check that new module dependencies have been properly installed after a migration/upgrade
            cr.execute("SELECT name from ir_module_module WHERE state IN ('to install', 'to upgrade')")
            module_list = [name for (name,) in cr.fetchall()]
            if module_list:
                _logger.error("Some modules have inconsistent states, some dependencies may be missing: %s", sorted(module_list))
    
            # STEP 3.6: apply remaining constraints in case of an upgrade
            registry.finalize_constraints()
    
            # STEP 4: Finish and cleanup installations
            if processed_modules:
                env = api.Environment(cr, SUPERUSER_ID, {})
    
                cr.execute("SELECT model from ir_model")
                for (model,) in cr.fetchall():
                    if model in registry:
                        env[model]._check_removed_columns(log=True)
                    elif _logger.isEnabledFor(logging.INFO):    # more an info that a warning...
                        _logger.runbot("Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model)
    
                # Cleanup orphan records
                env['ir.model.data']._process_end(processed_modules)
                env.flush_all()
    
            for kind in ('init', 'demo', 'update'):
                tools.config[kind] = {}
    
            # STEP 5: Uninstall modules to remove
            if update_module:
                # Remove records referenced from ir_model_data for modules to be
                # removed (and removed the references from ir_model_data).
                cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',))
                modules_to_remove = dict(cr.fetchall())
                if modules_to_remove:
                    env = api.Environment(cr, SUPERUSER_ID, {})
                    pkgs = reversed([p for p in graph if p.name in modules_to_remove])
                    for pkg in pkgs:
                        uninstall_hook = pkg.info.get('uninstall_hook')
                        if uninstall_hook:
                            py_module = sys.modules['odoo.addons.%s' % (pkg.name,)]
                            getattr(py_module, uninstall_hook)(cr, registry)
                            env.flush_all()
    
                    Module = env['ir.module.module']
                    Module.browse(modules_to_remove.values()).module_uninstall()
                    # Recursive reload, should only happen once, because there should be no
                    # modules to remove next time
                    cr.commit()
                    _logger.info('Reloading registry once more after uninstalling modules')
                    registry = odoo.modules.registry.Registry.new(
                        cr.dbname, force_demo, status, update_module
                    )
                    cr.reset()
                    registry.check_tables_exist(cr)
                    cr.commit()
                    return registry
    
            # STEP 5.5: Verify extended fields on every model
            # This will fix the schema of all models in a situation such as:
            #   - module A is loaded and defines model M;
            #   - module B is installed/upgraded and extends model M;
            #   - module C is loaded and extends model M;
            #   - module B and C depend on A but not on each other;
            # The changes introduced by module C are not taken into account by the upgrade of B.
            if models_to_check:
                registry.init_models(cr, list(models_to_check), {'models_to_check': True})
    
            # STEP 6: verify custom views on every model
            if update_module:
                env = api.Environment(cr, SUPERUSER_ID, {})
                env['res.groups']._update_user_groups_view()
                View = env['ir.ui.view']
                for model in registry:
                    try:
                        View._validate_custom_views(model)
                    except Exception as e:
                        _logger.warning('invalid custom view(s) for model %s: %s', model, tools.ustr(e))
    
            if report.wasSuccessful():
                _logger.info('Modules loaded.')
            else:
                _logger.error('At least one test failed when loading the modules.')
    
    
            # STEP 8: save installed/updated modules for post-install tests and _register_hook
            registry.updated_modules += processed_modules
    
            # STEP 9: call _register_hook on every model
            # This is done *exactly once* when the registry is being loaded. See the
            # management of those hooks in `Registry.setup_models`: all the calls to
            # setup_models() done here do not mess up with hooks, as registry.ready
            # is False.
            env = api.Environment(cr, SUPERUSER_ID, {})
            for model in env.values():
                model._register_hook()
            env.flush_all()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240

    0、初始化数据库

    这里判断数据库有没有被初始化,如果没有,就安装base模块

        initialize_sys_path()
    
        force = []
        if force_demo:
            force.append('demo')
    
        models_to_check = set()
    
        with registry.cursor() as cr:
            # prevent endless wait for locks on schema changes (during online
            # installs) if a concurrent transaction has accessed the table;
            # connection settings are automatically reset when the connection is
            # borrowed from the pool
            cr.execute("SET SESSION lock_timeout = '15s'")
            if not odoo.modules.db.is_initialized(cr):
                if not update_module:
                    _logger.error("Database %s not initialized, you can force it with `-i base`", cr.dbname)
                    return
                _logger.info("init db")
                odoo.modules.db.initialize(cr)
                update_module = True # process auto-installed modules
                tools.config["init"]["all"] = 1
                if not tools.config['without_demo']:
                    tools.config["demo"]['all'] = 1
    
            if 'base' in tools.config['update'] or 'all' in tools.config['update']:
                cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed'))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    step 1、加载base模块

    第一步就是加载base模块, 最后还加载了其他模块的语言包

    SELECT model || '.' || name FROM ir_model_fields WHERE translate IS TRUE   #原来pg使用|| 来拼接字符串的。
    
    registry._database_translated_fields = {row[0] for row in cr.fetchall()}    # 这个写法也很有意思,简洁
    
    • 1
    • 2
    • 3
     # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps)
            graph = odoo.modules.graph.Graph()
            graph.add_module(cr, 'base', force)
            if not graph:
                _logger.critical('module base cannot be loaded! (hint: verify addons-path)')
                raise ImportError('Module `base` cannot be loaded! (hint: verify addons-path)')
    
            if update_module and odoo.tools.table_exists(cr, 'ir_model_fields'):
                # determine the fields which are currently translated in the database
                cr.execute("SELECT model || '.' || name FROM ir_model_fields WHERE translate IS TRUE")
                registry._database_translated_fields = {row[0] for row in cr.fetchall()}   
      
            # processed_modules: for cleanup step after install
            # loaded_modules: to avoid double loading
            report = registry._assertion_report
            loaded_modules, processed_modules = load_module_graph(
                cr, graph, status, perform_checks=update_module,
                report=report, models_to_check=models_to_check)
    
            load_lang = tools.config.pop('load_language')
            if load_lang or update_module:
                # some base models are used below, so make sure they are set up
                registry.setup_models(cr)
    
            if load_lang:
                for lang in load_lang.split(','):
                    tools.load_language(cr, lang)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    控制台输出

    2023-11-04 07:58:50,981 1340 INFO ? odoo.service.server: HTTP service (werkzeug) running on LAPTOP-AV3CF7SO:8069 
    2023-11-04 07:58:50,987 1340 INFO odoo2 odoo.modules.loading: loading 1 modules...
    2023-11-04 07:58:51,008 1340 INFO odoo2 odoo.modules.loading: 1 modules loaded in 0.02s, 0 queries (+0 extra) 
    2023-11-04 07:58:51,154 1340 INFO odoo2 odoo.addons.base.models.ir_module: module base: loading translation file zh_CN for language zh_CN 
    2023-11-04 07:58:52,077 1340 INFO odoo2 odoo.addons.base.models.ir_module: module web: loading translation file zh_CN for language zh_CN 
    2023-11-04 07:58:52,256 1340 INFO odoo2 odoo.addons.base.models.ir_module: module base_setup: loading translation file zh_CN for language zh_CN 
    2023-11-04 07:58:52,282 1340 INFO odoo2 odoo.addons.base.models.ir_module: module bus: loading translation file zh_CN for language zh_CN 
    2023-11-04 07:58:52,295 1340 INFO odoo2 odoo.addons.base.models.ir_module: module web_tour: loading translation file zh_CN for language zh_CN 
    2023-11-04 07:58:52,304 1340 INFO odoo2 odoo.addons.base.models.ir_module: module mail: loading translation file zh_CN for language zh_CN 
    中间省略N行....
    sql_constraint:cf.report.define.field 
    2023-11-04 07:58:54,087 1340 INFO odoo2 odoo.tools.translate: Skipped deprecated occurrence sql_constraint:cf.report.define
    2023-11-04 07:58:54,087 1340 INFO odoo2 odoo.tools.translate: Skipped deprecated occurrence selection:cf.report.define,state
    2023-11-04 07:58:54,094 1340 INFO odoo2 odoo.addons.base.models.ir_module: module estate: no translation for language zh_CN
    2023-11-04 07:58:54,102 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_base: no translation for language zh_CN 
    2023-11-04 07:58:54,115 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_chp: no translation for language zh_CN 
    2023-11-04 07:58:54,122 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_gift: no translation for language zh_CN
    2023-11-04 07:58:54,129 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_jixiao: no translation for language zh_CN 
    2023-11-04 07:58:54,136 1340 INFO odoo2 odoo.addons.base.models.ir_module: module hx_tsl: no translation for language zh_CN
    2023-11-04 07:58:54,143 1340 INFO odoo2 odoo.addons.base.models.ir_module: module auth_totp: loading translation file zh_CN for 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    step 2、加载或者升级其他模块

            # STEP 2: Mark other modules to be loaded/updated
            if update_module:
                env = api.Environment(cr, SUPERUSER_ID, {})
                Module = env['ir.module.module']
                _logger.info('updating modules list')
                Module.update_list()
    
                _check_module_names(cr, itertools.chain(tools.config['init'], tools.config['update']))
    
                module_names = [k for k, v in tools.config['init'].items() if v]
                if module_names:
                    modules = Module.search([('state', '=', 'uninstalled'), ('name', 'in', module_names)])
                    if modules:
                        modules.button_install()
    
                module_names = [k for k, v in tools.config['update'].items() if v]
                if module_names:
                    modules = Module.search([('state', 'in', ('installed', 'to upgrade')), ('name', 'in', module_names)])
                    if modules:
                        modules.button_upgrade()
    
                env.flush_all()
                cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
                Module.invalidate_model(['state'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    如果没有,这一步就跳过了

    step 3、加载除了base之外的其他模块

    1、分两个步骤完成,第一步加载所有已经安装的或者部分安装(需要升级),为第二步提供一个一致性的系统。第二步是安装新的模块。

    我们在第一步中考虑了to_remove 的模块,因为他们是“已安装”模块的一部分, 他们将在step 6 去处理。

    2、这里不得不循环处理,因为要处理模块之间的依赖关系

    # STEP 3: Load marked modules (skipping base which was done in STEP 1)
            # IMPORTANT: this is done in two parts, first loading all installed or
            #            partially installed modules (i.e. installed/to upgrade), to
            #            offer a consistent system to the second part: installing
            #            newly selected modules.
            #            We include the modules 'to remove' in the first step, because
            #            they are part of the "currently installed" modules. They will
            #            be dropped in STEP 6 later, before restarting the loading
            #            process.
            # IMPORTANT 2: We have to loop here until all relevant modules have been
            #              processed, because in some rare cases the dependencies have
            #              changed, and modules that depend on an uninstalled module
            #              will not be processed on the first pass.
            #              It's especially useful for migrations.
            previously_processed = -1
            #  循环加载处理相关模块
            while previously_processed < len(processed_modules):
                previously_processed = len(processed_modules)
                processed_modules += load_marked_modules(cr, graph,
                    ['installed', 'to upgrade', 'to remove'],
                    force, status, report, loaded_modules, update_module, models_to_check)
                if update_module:
                    processed_modules += load_marked_modules(cr, graph,
                        ['to install'], force, status, report,
                        loaded_modules, update_module, models_to_check)
    		
            # 处理需要升级的模块
            if update_module:
                # set up the registry without the patch for translated fields
                database_translated_fields = registry._database_translated_fields
                registry._database_translated_fields = ()
                registry.setup_models(cr)
                # determine which translated fields should no longer be translated,
                # and make their model fix the database schema
                models_to_untranslate = set()
                for full_name in database_translated_fields:
                    model_name, field_name = full_name.rsplit('.', 1)
                    if model_name in registry:
                        field = registry[model_name]._fields.get(field_name)
                        if field and not field.translate:
                            _logger.debug("Making field %s non-translated", field)
                            models_to_untranslate.add(model_name)
                registry.init_models(cr, list(models_to_untranslate), {'models_to_check': True})
    
            registry.loaded = True
            registry.setup_models(cr)
    
            # check that all installed modules have been loaded by the registry
            env = api.Environment(cr, SUPERUSER_ID, {})
            Module = env['ir.module.module']
            modules = Module.search(Module._get_modules_to_load_domain(), order='name')
            missing = [name for name in modules.mapped('name') if name not in graph]
            if missing:
                _logger.error("Some modules are not loaded, some dependencies or manifest may be missing: %s", missing)
    
            # STEP 3.5: execute migration end-scripts
            migrations = odoo.modules.migration.MigrationManager(cr, graph)
            for package in graph:
                migrations.migrate_module(package, 'end')
    
            # check that new module dependencies have been properly installed after a migration/upgrade
            cr.execute("SELECT name from ir_module_module WHERE state IN ('to install', 'to upgrade')")
            module_list = [name for (name,) in cr.fetchall()]
            if module_list:
                _logger.error("Some modules have inconsistent states, some dependencies may be missing: %s", sorted(module_list))
    
            # STEP 3.6: apply remaining constraints in case of an upgrade
            registry.finalize_constraints()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    控制台输出:

    2023-11-04 08:16:23,488 11076 INFO odoo2 odoo.modules.loading: loading 54 modules... 
    2023-11-04 08:16:23,882 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.hx_chp.models.change_point is not overriding the create method 
    
    2023-11-04 08:16:23,944 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.hx_tsl.models.hx_tsl_info is not overriding the create method in batch
    2023-11-04 08:16:24,292 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.cfprint.models.cfprint_server_user_map is not overriding the create method in batch
    2023-11-04 08:16:25,047 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.cf_report_designer.models.data_model_3 is not overriding the create method in batch
    2023-11-04 08:16:25,069 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.cf_report_designer.models.data_model_4 is not overriding the create method in batch
    2023-11-04 08:16:25,071 11076 WARNING odoo2 odoo.api.create: The model odoo.addons.cf_report_designer.models.data_model_4 is not overriding the create method in batch
    2023-11-04 08:16:25,416 11076 INFO odoo2 odoo.modules.loading: 54 modules loaded in 1.93s, 0 queries (+0 extra) 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    step 4、完成并且清理安装过程

    基本就是一些善后过程,正常情况下不会执行

    # STEP 4: Finish and cleanup installations
            if processed_modules:
                env = api.Environment(cr, SUPERUSER_ID, {})
    
                cr.execute("SELECT model from ir_model")
                for (model,) in cr.fetchall():
                    if model in registry:
                        env[model]._check_removed_columns(log=True)
                    elif _logger.isEnabledFor(logging.INFO):    # more an info that a warning...
                        _logger.runbot("Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model)
    
                # Cleanup orphan records
                env['ir.model.data']._process_end(processed_modules)
                env.flush_all()
    
            for kind in ('init', 'demo', 'update'):
                tools.config[kind] = {}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    step 5、卸载相关模块

    SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',)
    
    • 1

    如果配置了uninstall_hook,要在这里执行。 然后调用module_uninstall()方法来卸载

    Module.browse(modules_to_remove.values()).module_uninstall()
    
    • 1

    卸载完成之后,刷新注册表。

    5.5 是要处理一些模型之间的依赖关系。

    # STEP 5: Uninstall modules to remove
            if update_module:
                # Remove records referenced from ir_model_data for modules to be
                # removed (and removed the references from ir_model_data).
                cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',))
                modules_to_remove = dict(cr.fetchall())
                if modules_to_remove:
                    env = api.Environment(cr, SUPERUSER_ID, {})
                    pkgs = reversed([p for p in graph if p.name in modules_to_remove])
                    for pkg in pkgs:
                        uninstall_hook = pkg.info.get('uninstall_hook')
                        if uninstall_hook:
                            py_module = sys.modules['odoo.addons.%s' % (pkg.name,)]
                            getattr(py_module, uninstall_hook)(cr, registry)
                            env.flush_all()
    
                    Module = env['ir.module.module']
                    Module.browse(modules_to_remove.values()).module_uninstall()
                    # Recursive reload, should only happen once, because there should be no
                    # modules to remove next time
                    cr.commit()
                    _logger.info('Reloading registry once more after uninstalling modules')
                    registry = odoo.modules.registry.Registry.new(
                        cr.dbname, force_demo, status, update_module
                    )
                    cr.reset()
                    registry.check_tables_exist(cr)
                    cr.commit()
                    return registry
    
            # STEP 5.5: Verify extended fields on every model
            # This will fix the schema of all models in a situation such as:
            #   - module A is loaded and defines model M;
            #   - module B is installed/upgraded and extends model M;
            #   - module C is loaded and extends model M;
            #   - module B and C depend on A but not on each other;
            # The changes introduced by module C are not taken into account by the upgrade of B.
            if models_to_check:
                registry.init_models(cr, list(models_to_check), {'models_to_check': True})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    step 6、确认每个模型相关的视图

            # STEP 6: verify custom views on every model
            if update_module:
                env = api.Environment(cr, SUPERUSER_ID, {})
                env['res.groups']._update_user_groups_view()
                View = env['ir.ui.view']
                for model in registry:
                    try:
                        View._validate_custom_views(model)
                    except Exception as e:
                        _logger.warning('invalid custom view(s) for model %s: %s', model, tools.ustr(e))
    
            if report.wasSuccessful():
                _logger.info('Modules loaded.')
            else:
                _logger.error('At least one test failed when loading the modules.')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    控制台输出

    2023-11-04 08:35:43,841 11076 INFO odoo2 odoo.modules.loading: Modules loaded. 
    
    • 1

    step 8、保存安装或者升级的视图

    为了post-install测试 和调用_register_hook, step7 哪去了????

            # STEP 8: save installed/updated modules for post-install tests and _register_hook
            registry.updated_modules += processed_modules
    
    • 1
    • 2

    step 9、调用_register_hook

    对每个model模型调用_register_hook,每次启动的时候都会调用,能干什么呢?

            # STEP 9: call _register_hook on every model
            # This is done *exactly once* when the registry is being loaded. See the
            # management of those hooks in `Registry.setup_models`: all the calls to
            # setup_models() done here do not mess up with hooks, as registry.ready
            # is False.
            env = api.Environment(cr, SUPERUSER_ID, {})
            for model in env.values():
                model._register_hook()
            env.flush_all()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    models.py

        def _register_hook(self):
            """ stuff to do right after the registry is built """
    
        def _unregister_hook(self):
            """ Clean up what `~._register_hook` has done. """
    
    • 1
    • 2
    • 3
    • 4
    • 5

    _register_hook 有什么用?

    可以在模块加载完之后动态修改模型的一些属性值。

    比如修改_rec_name

    def  _register_hook(self):
    	setattr(type(self),'_rec_name', 'myname')
    
    • 1
    • 2

    安装模块的时候也会执行load_modules函数重新加载所有的模块,如果你希望你的逻辑只有在启动的时候执行而不是安装模块的时候执行,在context中有个变量可以区分。

    哪个变量?

  • 相关阅读:
    C++-STL-map:map插入元素的几种方式【用数组方式插入数据】【用insert函数插入pair数据】【用insert函数插入value_type数据】
    java毕业设计共享充电宝系统(附源码、数据库)
    Linux CentOS7 yum仓库
    计算机视觉五大核心研究任务全解:分类识别、检测分割、人体分析、三维视觉、视频分析
    文件操作防护
    Activity生命周期
    Python绘图系统24:绘图类型和坐标映射的关系
    基于Java的大学生救援队网站
    uniapp开发h5引入第三方js(sdk)
    基于GoFrame+Vue+ElementUI搭建的博客管理系统
  • 原文地址:https://blog.csdn.net/jiafeitutu/article/details/134220723