Разрешение ошибки KeyError в Odoo 13, где необходимый ключ хранится в файле /security.xml

Попробуйте переустановить набор пользовательских модулей Odoo 13 на новой виртуальной машине на базе Ubuntu. Для одного из модулей (material_purchase_requisitions) я постоянно сталкиваюсь со следующей ошибкой сервера в момент установки (сообщение об ошибке сокращено до самой важной части):

Odoo Server Error

Traceback (most recent call last):
  File "/home/odoo13/odoo/odoo/tools/cache.py", line 85, in lookup
    r = d[key]
  File "/home/odoo13/odoo/odoo/tools/func.py", line 69, in wrapper
    return func(self, *args, **kwargs)
  File "/home/odoo13/odoo/odoo/tools/lru.py", line 44, in __getitem__
    a = self.d[obj].me
KeyError: ('ir.model.data', <function IrModelData.xmlid_lookup at 0x7f476ef59e50>, 'material_purchase_requisitions.inventory_keeper_manager_role')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/odoo13/odoo/odoo/tools/convert.py", line 712, in parse
    self._tag_root(de)
  File "/home/odoo13/odoo/odoo/tools/convert.py", line 674, in _tag_root
    f(rec)
  File "/home/odoo13/odoo/odoo/tools/convert.py", line 674, in _tag_root
    f(rec)
  File "/home/odoo13/odoo/odoo/tools/convert.py", line 472, in _tag_menuitem
    group_id = self.id_get(group)
  File "/home/odoo13/odoo/odoo/tools/convert.py", line 657, in id_get
    res = self.model_id_get(id_str, raise_if_not_found)
  File "/home/odoo13/odoo/odoo/tools/convert.py", line 663, 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 "/home/odoo13/odoo/odoo/addons/base/models/ir_model.py", line 1697, in xmlid_to_res_model_res_id
    return self.xmlid_lookup(xmlid)[1:3]
  File "<decorator-gen-24>", line 2, in xmlid_lookup
  File "/home/odoo13/odoo/odoo/tools/cache.py", line 90, in lookup
    value = d[key] = self.method(*args, **kwargs)
  File "/home/odoo13/odoo/odoo/addons/base/models/ir_model.py", line 1686, in xmlid_lookup
    raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: material_purchase_requisitions.inventory_keeper_manager_role

Указанный отсутствующий/неопознанный ключ (inventory_keeper_manager_role) находится в файле security.xml модуля и используется для создания пользовательских групп пользователей по правам доступа:

<?xml version = "1.0" encoding = "utf-8"?>
<odoo>
    <data noupdate = "0">

        <record model = "ir.module.category" id = "purchase_requisition_role">
            <field name = "name">Material Purchase Requisition</field>
        </record>

        <record id = "group_purchase_requisition_user" model = "res.groups">
            <field name = "name">Material Purchase Requisition User</field>
            <field name = "implied_ids" eval = "[(4, ref('stock.group_stock_user'))]"/>
            <field name = "category_id" ref = "purchase_requisition_role"/>
        </record>
        
        <record id = "group_all_administrator" model = "res.groups">
            <field name = "name">Administrator </field>
             <field name = "implied_ids" eval = "[
             (4, ref('base.group_user')),
             (4, ref('material_purchase_requisitions.group_purchase_requisition_department')),
             (4, ref('material_purchase_requisitions.inventory_keeper_manager_role')),
             (4, ref('material_purchase_requisitions.purchase_officer_role')),
             ]"/>
            <field name = "category_id" ref = "purchase_requisition_role"/>
            <field name = "users" eval = "[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
        </record>

        <record id = "group_purchase_requisition_department" model = "res.groups">
            <field name = "name">Material Purchase Requisition Department Manager</field>
            <field name = "implied_ids" eval = "[(4, ref('base.group_user'))]"/>
            <field name = "category_id" ref = "purchase_requisition_role"/>
        </record>

         <record id = "inventory_keeper_role" model = "res.groups">
             <field name = "name">Inventory Keeper</field>
             <field name = "implied_ids" eval = "[(4, ref('base.group_user'))]"/>
             <field name = "category_id" ref = "purchase_requisition_role"/>
        </record>

        <record id = "inventory_keeper_manager_role" model = "res.groups">
             <field name = "name">Inventory Manager</field>
             <field name = "implied_ids" eval = "[(4, ref('material_purchase_requisitions.inventory_keeper_role'))]"/>
             <field name = "category_id" ref = "purchase_requisition_role"/>
        </record>

        <record id = "purchase_officer_role" model = "res.groups">
             <field name = "name">Purchase Officer</field>
             <field name = "implied_ids" eval = "[(4, ref('base.group_user'))]"/>
             <field name = "category_id" ref = "purchase_requisition_role"/>
        </record>
        
        <record id = "purchase_requisition_own_rule" model = "ir.rule">
            <field name = "name">Employee Material Purchase Requistion Own</field>
            <field name = "model_id" ref = "model_material_purchase_requisition"/>
            <field name = "domain_force">[('employee_id.user_id','=',user.id)]</field>
            <field name = "groups" eval = "[(4, ref('base.group_user'))]"/>
        </record>

        <record id = "purchase_requisition_line_department_manager_rule" model = "ir.rule">
            <field name = "name">Department Manager Material Purchase Requistion</field>
            <field name = "model_id" ref = "model_material_purchase_requisition"/>
            <field name = "domain_force">[('employee_id.department_id.manager_id.user_id','=',user.id)]</field>
            <field name = "groups" eval = "[(4, ref('material_purchase_requisitions.group_purchase_requisition_department'))]"/>
        </record>

        <record id = "purchase_requisition_all_rule" model = "ir.rule">
            <field name = "name">Material Purcahse Requisitions All</field>
            <field name = "model_id" ref = "model_material_purchase_requisition"/>
            <field name = "domain_force">[(1,'=',1)]</field>
            <field name = "groups" eval = "[(4, ref('material_purchase_requisitions.group_all_administrator')),
                                        (4, ref('material_purchase_requisitions.inventory_keeper_role')),
                                        (4, ref('material_purchase_requisitions.purchase_officer_role'))]"/>
        </record>

        <record id = "purchase_requisition_line_all_rule" model = "ir.rule">
            <field name = "name">Material Purcahse Requisitions Line All</field>
            <field name = "model_id" ref = "model_material_purchase_requisition_line"/>
            <field name = "domain_force">[(1,'=',1)]</field>
            <field name = "groups" eval = "[(4, ref('material_purchase_requisitions.group_all_administrator')),
                                        (4, ref('material_purchase_requisitions.inventory_keeper_role')),
                                        (4, ref('material_purchase_requisitions.purchase_officer_role'))]"/>
        </record>
    </data>
</odoo>

Учитывая, что я могу точно проследить расположение ключа и его реализацию в коде, и, насколько я могу судить, синтаксических ошибок нет. Файлы также вызываются в правильном порядке в файле манифеста модуля. Итак, что вызывает появление KeyError?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

вы можете попробовать переместить запись, которая определяет inventory_keeper_manager_role, непосредственно перед ее вызовом group_all_administrator

Ответ принят как подходящий

Файлы данных в манифесте и сами данные (например, узлы XML или строки CSV), как в вашем security.xml, обрабатываются последовательно. Внешние идентификаторы или идентификаторы XML сохраняются в таблице ir_model_data и создаются или обновляются до создания или обновления фактических данных (в файле Security.xml обычно группы доступа).

Ваша группа доступа с идентификатором xml group_all_administrator использует другой идентификатор xml в поле implied_ids. Odoo обработает это в базе данных, но только если у нее есть все необходимые данные. Но идентификатор xml inventory_keeper_manager_role еще не был создан.

Поэтому вам нужно получить свой заказ прямо в этом файле. Я не изучил все в этом файле, но, по крайней мере, вам нужно переместить группы с идентификатором xml inventory_keeper_manager_role и inventory_keeper_role перед идентификатором xml group_all_administrator.

Другие вопросы по теме