odoo / odoo

Odoo. Open Source Apps To Grow Your Business.
https://www.odoo.com
Other
38.05k stars 24.7k forks source link

[17.0] Exception when installing a simple module with one dependency and one data record addition #142512

Open fractalf opened 10 months ago

fractalf commented 10 months ago

Error message

ValueError: External ID not found in the system: account.1_chart1918

(full exception at the end of the issue)

Version

Running version 17 in a docker container using the deb here: https://download.odoo.com/17.0/nightly/deb/odoo_17.0.20231116_all.deb

Setup (for reproduction)

__manifest__.py

# -*- coding: utf-8 -*-
{
    'name': 'My Module',
    'version': '17.0.1.0.0',
    'category': 'Hidden',
    'sequence': 0,
    'summary': 'Test module',
    'license': 'LGPL-3',
    'depends': [
        'l10n_no',
    ],
    'data': [
        'my_test.xml',
    ],
    'installable': True,
    'application': True,
}

my_test.xml

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <record id="my_test" model="account.journal">
            <field name="name">Test</field>
            <field name="code">TEST</field>
            <field name="type">cash</field>
            <field name="sequence">20</field>
            <field name="profit_account_id" ref="account.1_chart1918" />
            <field name="loss_account_id" ref="account.1_chart1918" />
        </record>
    </data>
</odoo>

i10n_no

This is a short snippet from the record I'm trying to link up

addons/l10n_no/data/template/account.account-no.csv

"id","code","name","account_type","tag_ids","reconcile","name@nb_NO"
..
"chart1918","1918","Cash differentials","asset_current","","False","Kassedifferenser"
..

Description

Ok, this is quite weird..

1 - Described setup => fails

Running the setup described above results in failure

ValueError: External ID not found in the system: account.1_chart1918

2 - Try doing it in two steps (debug) => works

Comment out the custom record like this

..
    'data': [
        # 'my_test.xml',
    ],
..

..then install the module, and check the database

image

...it's there.

Remove the comment to prepare the custom data record install

..
    'data': [
        'my_test.xml',
    ],
..

..then upgrade the module.

And it works!

Conclusion

Something is wrong here, step 1 above should work in one go, right?

Comment

I should mention that I think it's very strange that I should use the ref 1_chart1918 and not just chart1918 (without the 1_ part which I don't know where comes from, but that's what's in the database..)

Ofc I tried with with just ref to chart1918 as well, but that failed also

Full exception error stack

2023-11-17 12:22:41,221 37 INFO ff odoo.modules.loading: loading my_module/my_test.xml 
2023-11-17 12:22:41,239 37 WARNING ff odoo.modules.loading: Transient module states were reset 
2023-11-17 12:22:41,241 37 ERROR ff odoo.modules.registry: Failed to load registry 
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odoo/tools/cache.py", line 99, in lookup
    r = d[key]
        ~^^^^^
  File "/usr/lib/python3/dist-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/func.py", line 87, in locked
    return func(inst, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/lru.py", line 34, in __getitem__
    a = self.d[obj]
        ~~~~~~^^^^^
KeyError: ('ir.model.data', <function IrModelData._xmlid_lookup at 0x7fbb1a058f40>, 'account.1_chart1918')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 556, in _tag_root
    f(rec)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 421, in _tag_record
    f_val = self.id_get(f_ref, raise_if_not_found=nodeattr2bool(rec, 'forcecreate', True))
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 538, in id_get
    res = self.model_id_get(id_str, raise_if_not_found)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 544, in model_id_get
    return self.env['ir.model.data']._xmlid_to_res_model_res_id(id_str, raise_if_not_found=raise_if_not_found)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/base/models/ir_model.py", line 2171, in _xmlid_to_res_model_res_id
    return self._xmlid_lookup(xmlid)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/cache.py", line 104, in lookup
    value = d[key] = self.method(*args, **kwargs)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/base/models/ir_model.py", line 2164, in _xmlid_lookup
    raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: account.1_chart1918

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odoo/modules/registry.py", line 113, in new
    odoo.modules.load_modules(registry, force_demo, status, update_module)
  File "/usr/lib/python3/dist-packages/odoo/modules/loading.py", line 480, in load_modules
    processed_modules += load_marked_modules(env, graph,
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/modules/loading.py", line 364, in load_marked_modules
    loaded, processed = load_module_graph(
                        ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/modules/loading.py", line 227, in load_module_graph
    load_data(env, idref, mode, kind='data', package=package)
  File "/usr/lib/python3/dist-packages/odoo/modules/loading.py", line 71, in load_data
    tools.convert_file(env, package.name, filename, idref, mode, noupdate, kind)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 627, in convert_file
    convert_xml_import(env, module, fp, idref, mode, noupdate)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 693, in convert_xml_import
    obj.parse(doc.getroot())
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 613, in parse
    self._tag_root(de)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 556, in _tag_root
    f(rec)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 569, in _tag_root
    raise ParseError('while parsing %s:%s, somewhere inside\n%s' % (
odoo.tools.convert.ParseError: while parsing /mnt/extra-addons/my_module/my_test.xml:4, somewhere inside
<record id="my_test" model="account.journal">
            <field name="name">Test</field>
            <field name="code">TEST</field>
            <field name="type">cash</field>
            <field name="sequence">20</field>
            <field name="profit_account_id" ref="account.1_chart1918"/>
            <field name="loss_account_id" ref="account.1_chart1918"/>
        </record>
2023-11-17 12:22:41,260 37 ERROR ff odoo.http: Exception during request handling. 
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odoo/tools/cache.py", line 99, in lookup
    r = d[key]
        ~^^^^^
  File "/usr/lib/python3/dist-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/func.py", line 87, in locked
    return func(inst, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/lru.py", line 34, in __getitem__
    a = self.d[obj]
        ~~~~~~^^^^^
KeyError: ('ir.model.data', <function IrModelData._xmlid_lookup at 0x7fbb1a058f40>, 'account.1_chart1918')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 556, in _tag_root
    f(rec)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 421, in _tag_record
    f_val = self.id_get(f_ref, raise_if_not_found=nodeattr2bool(rec, 'forcecreate', True))
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 538, in id_get
    res = self.model_id_get(id_str, raise_if_not_found)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 544, in model_id_get
    return self.env['ir.model.data']._xmlid_to_res_model_res_id(id_str, raise_if_not_found=raise_if_not_found)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/base/models/ir_model.py", line 2171, in _xmlid_to_res_model_res_id
    return self._xmlid_lookup(xmlid)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/cache.py", line 104, in lookup
    value = d[key] = self.method(*args, **kwargs)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/base/models/ir_model.py", line 2164, in _xmlid_lookup
    raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: account.1_chart1918

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 2157, in __call__
    response = request._serve_db()
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 1732, in _serve_db
    return service_model.retrying(self._serve_ir_http, self.env)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/service/model.py", line 133, in retrying
    result = func()
             ^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 1759, in _serve_ir_http
    response = self.dispatcher.dispatch(rule.endpoint, args)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 1960, in dispatch
    result = self.request.registry['ir.http']._dispatch(endpoint)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/base/models/ir_http.py", line 207, in _dispatch
    result = endpoint(**request.params)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 722, in route_wrapper
    result = endpoint(self, *args, **params_ok)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/web/controllers/dataset.py", line 28, in call_button
    action = self._call_kw(model, method, args, kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/web/controllers/dataset.py", line 20, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/api.py", line 466, in call_kw
    result = _call_kw_multi(method, model, args, kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/api.py", line 453, in _call_kw_multi
    result = method(recs, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/base/models/ir_module.py", line 75, in check_and_log
    return method(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/base/models/ir_module.py", line 459, in button_immediate_install
    return self._button_immediate_function(type(self).button_install)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/addons/base/models/ir_module.py", line 583, in _button_immediate_function
    registry = modules.registry.Registry.new(self._cr.dbname, update_module=True)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/tools/func.py", line 87, in locked
    return func(inst, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/modules/registry.py", line 113, in new
    odoo.modules.load_modules(registry, force_demo, status, update_module)
  File "/usr/lib/python3/dist-packages/odoo/modules/loading.py", line 480, in load_modules
    processed_modules += load_marked_modules(env, graph,
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/modules/loading.py", line 364, in load_marked_modules
    loaded, processed = load_module_graph(
                        ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/odoo/modules/loading.py", line 227, in load_module_graph
    load_data(env, idref, mode, kind='data', package=package)
  File "/usr/lib/python3/dist-packages/odoo/modules/loading.py", line 71, in load_data
    tools.convert_file(env, package.name, filename, idref, mode, noupdate, kind)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 627, in convert_file
    convert_xml_import(env, module, fp, idref, mode, noupdate)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 693, in convert_xml_import
    obj.parse(doc.getroot())
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 613, in parse
    self._tag_root(de)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 556, in _tag_root
    f(rec)
  File "/usr/lib/python3/dist-packages/odoo/tools/convert.py", line 569, in _tag_root
    raise ParseError('while parsing %s:%s, somewhere inside\n%s' % (
odoo.tools.convert.ParseError: while parsing /mnt/extra-addons/my_module/my_test.xml:4, somewhere inside
<record id="my_test" model="account.journal">
            <field name="name">Test</field>
            <field name="code">TEST</field>
            <field name="type">cash</field>
            <field name="sequence">20</field>
            <field name="profit_account_id" ref="account.1_chart1918"/>
            <field name="loss_account_id" ref="account.1_chart1918"/>
        </record>
fractalf commented 5 months ago

I'd like to bump this in hope that someone with greater knowledge can look at this. It's still a bug now 6 months later (tried today with latest from nightly)

It's really easy to reproduce. Just boot up a docker container with the latest Odoo17 from nightly (or any v17 I guess) and add the two files provided here above, install the module and bam, errors..

fractalf commented 5 months ago

I want to add another debug point

3 - Manually first install l10n_no and then this module => works

If I manually install the l10n_no module from Apps and then when done manually install the debug/test module provided here it works.

So the problem seems to be how Odoo handles dependencies

madprog commented 5 months ago

Hello @fractalf, The accounts of a Chart of Accounts are instantiated once per company, from a template. When the chart of accounts is installed, account.chart.template:_load gets called, which calls _get_chart_template_data. This second method gets models and to-be-called methods from self._template_register, which is filled up by methods decorated with @template such as _get_account_account. In the end, account.chart.template:_parse_csv is called to actually load the files inside the {module}/data/template folder.

This means that the record which you are trying to reference is not loaded at the module installation time, but at the time when the Chart of Accounts Template is instantiated for a company. Furthermore, as a Chart of Account may be instantiated once for each company of a database, the XML ids are prefixed with the id of the company (hence the 1_ as if you only have one company it will have the id 1).

About your need to reference an account from the chart of accounts directly from your module, I guess that the best way would be to provide your own template files and have them loaded along with the Chart of Accounts, but I am not sure neither how to do this, nor if this would also work if you first install the l10n_no module, instantiate the CoA and then install your custom module. Maybe someone else with more knowledge about l10n modules than me could provide more information about this.