Утиліти оновлення

Утиліти оновлення - це бібліотека, що містить допоміжні функції для полегшення написання скриптів оновлення. Ця бібліотека, яка використовується Odoo для скриптів оновлення стандартних модулів, забезпечує надійність і допомагає пришвидшити процес оновлення:

  • Допоміжні функції допомагають забезпечити узгодженість даних у базі даних.

  • Він обробляє непрямі посилання на оновлені записи.

  • Дозволяє викликати функції та уникнути написання коду, заощаджуючи час та зменшуючи ризики розробки.

  • Помічники дозволяють зосередитися на тому, що важливо для оновлення, і не думати про деталі.

Встановлення

Клонуйте репозиторій Репозиторій оновлення утиліт локально та запустіть odoo з каталогом src на початку параметра --upgrade-path.

$ ./odoo-bin --upgrade-path=/path/to/upgrade-util/src,/path/to/other/upgrade/script/directory [...]

На платформах, де ви не керуєте Odoo самостійно, ви можете встановити цю бібліотеку через pip:

$ python3 -m pip install git+https://github.com/odoo/upgrade-util@master

На Odoo.sh рекомендується додати його до requirements.txt користувацького репозиторію. Для цього додайте наступний рядок усередині файлу:

odoo_upgrade @ git+https://github.com/odoo/upgrade-util@master

Використання утиліт оновлення

Після встановлення для скриптів оновлення доступні такі пакети:

  • odoo.upgrade.util: сам помічник.

  • odoo.upgrade.testing: базові класи TestCase.

Щоб використовувати його в скриптах оновлення, просто імпортуйте його:

from odoo.upgrade import util


def migrate(cr, version):
   # Rest of the script

Тепер допоміжні функції доступні для виклику через util.

Функції утиліт

Утиліти оновлення - це бібліотека, що містить допоміжні функції для полегшення написання скриптів оновлення. Ця бібліотека, яка використовується Odoo для скриптів оновлення стандартних модулів, забезпечує надійність і допомагає пришвидшити процес оновлення.

Примітка

Параметр cr у корисних функціях завжди посилається на курсор бази даних. Передайте отриманий параметр як параметр у migrate(). Не всім функціям потрібен цей параметр.

Модулі

Функції утиліти для операцій на рівні модуля.

У більшості випадків операції з модулями (перейменування, об’єднання, видалення тощо) слід виконувати в скрипті base. Причина полягає в тому, що після оновлення модуля base вся інформація щодо модулів повинна бути вже встановлена в базі даних, щоб процес оновлення працював коректно. Опція командного рядка --pre-upgrade-scripts (доступна в Odoo 16) дозволяє запускати скрипти оновлення перед завантаженням base. Це рекомендований спосіб виконання операцій з модулями після значного оновлення.

force_install_module(cr, module, if_installed=None, reason='it has been explicitly asked for')[source]

Змусити ORM встановити модуль.

Параметри
  • module (str) – назва модуля для встановлення

  • if_installed (list(str) or None) – примусово встановлювати лише тоді, коли ці модулі вже встановлені

повернути str

новий стан модуля

force_upgrade_of_fresh_module(cr, module, init=True)[source]

Примусово запустити виконання скриптів оновлення для модуля, що встановлюється.

Стандартна версія Odoo не запускає скрипти оновлення під час інсталяції модуля. Це логічно, оскільки, з технічної точки зору, модуль не оновлюється. Проте трапляються випадки, коли (новий) модуль повинен виконати певні операції для правильної інсталяції, наприклад, отримати дані з іншого модуля. Це часто трапляється, коли модуль функціонально розділений на кілька модулів.

Параметри
  • module (str) – назва модуля, для якого потрібно примусово виконати скрипти оновлення

  • init (bool) – чи встановити модуль у режим init

Перебування в режимі ініціалізації має побічний ефект неврахування прапорців noupdate ні в XML-файлі, ні в ir_model_data.

merge_module(cr, old, into, update_dependers=True, xmlid_mapping=None)[source]

Об’єднати модуль з іншим.

Ця функція переміщує всі посилання та записи з вихідного модуля до цільового модуля.

Попередження

Ця функція не видаляє жодного запису. Вона видаляє XMLID з вихідного модуля, назва яких конфліктує з модулем призначення, якщо їх не перейменовано явно через параметр xmlid_mapping.

Параметри
  • old (str) – назва модуля, який потрібно об’єднати

  • into (str) – назва модуля, з яким потрібно об’єднати

  • update_dependers (bool) – чи оновлюються залежності модулів, що залежать від old

  • xmlid_mapping (dict) – необов’язкове відображення {old_name: new_name} для перейменування XMLID у процесі об’єднання. Використовуйте це, якщо XMLID з old інакше конфліктував би за назвою з тим, що вже є в into. Див. rename_xmlid()

module_installed(cr, module)[source]

Повертає інформацію про те, чи встановлено модуль.

Параметри

module (str) – назва модуля для перевірки

Тип повернення

bool

Див. modules_installed().

modules_installed(cr, *modules)[source]

Повертає, чи встановлено всі задані модулі.

Параметри

modules (str) – одна або кілька назв модулів для перевірки (variadic)

Тип повернення

bool

Примітка

У контексті оновлень модуль вважається встановленим, якщо він позначений для оновлення або встановлення; навіть якщо вони ще не повністю встановлені.

move_model(cr, model, from_module, to_module, move_data=False, keep=())[source]

Переміщення моделі з одного модуля до іншого.

Параметри
  • model (str) – назва моделі для переміщення

  • from_module (str) – назва модуля, де модель спочатку визначена

  • to_module (str) – назва цільового модуля, куди потрібно перемістити модель

  • move_data (bool) – чи також оновлювати ir_model_data для записів моделі

  • keep (list(str)) – список XML-ідентифікаторів, які потрібно зберегти, а не переміщувати

Цю функцію можна викликати для переміщення змін моделі до іншого модуля. Оскільки вона не може розрізнити вихідну модель від успадкованої, вона викликає виняток, якщо цільовий модуль не встановлено.

remove_module(cr, module)[source]

Повністю видалити модуль.

Ця операція еквівалентна деінсталяції та видаленню всіх посилань на модуль - жодних слідів від нього в базі даних не залишається.

Параметри

module (str) – назва модуля, який потрібно видалити

Попередження

Оскільки ця функція видаляє всі дані, пов’язані з модулем, переконайтеся, що ви перепризначили записи перед викликом цієї функції.

remove_theme(cr, theme, base_theme=None)[source]

Деінсталювати модуль теми.

Попередження

Цю функцію можна використовувати лише у скриптах post-.

Див. remove_module() та uninstall_theme().

rename_module(cr, old, new)[source]

Перейменувати модуль та всі посилання на нього.

Параметри
  • old (str) – поточна назва модуля для перейменування

  • new (str) – нова назва модуля для перейменування

uninstall_module(cr, module)[source]

Деінсталювати та видалити всі записи, що належать модулю.

Параметри

module (str) – назва модуля для видалення

uninstall_theme(cr, theme, base_theme=None)[source]

Деінсталюйте модуль теми та видаліть його з вебсайтів.

Параметри
  • theme (str) – назва модуля теми, який потрібно деінсталювати

  • base_theme (str or None) – якщо не None, спочатку вивантажити цю базову тему

Попередження

Цю функцію можна використовувати лише в post- скриптах модуля website, оскільки вона спирається на ORM.

Див. remove_theme() та uninstall_module().

Моделі

Допоміжні функції для модифікації моделей.

Операції з моделлю найкраще виконувати в pre- скриптах задіяних модулів.

merge_model(cr, source, target, drop_table=True, fields_mapping=None, ignore_m2m=())[source]

Об’єднати модель з іншою.

Ця функція переміщує всі посилання з моделі source в модель target і видаляє модель source та її посилання. За замовчуванням, з моделі-джерела в модель-ціль переміщуються лише поля з однаковими іменами в обох моделях, але за бажанням можна надати відповідність полів з різними іменами.

Попередження

Ця функція не переміщує записи з моделі source до моделі target.

Параметри
  • source (str) – назва моделі, яку потрібно об’єднати

  • target (str) – назва цільової моделі для об’єднання

  • drop_table (bool) – чи слід видаляти таблицю вихідної моделі

  • fields_mapping (dict or None) – зіставлення назв полів з вихідної моделі в цільову, при використанні None переміщуються лише поля з однаковими назвами

  • ignore_m2m (list(str) or str) – список таблиць m2m, які ігноруються для видалення з вихідної моделі.

remove_inherit_from_model(cr, model, inherit, keep=(), skip_inherit=(), with_inherit_parents=True, skip_update_references=())[source]

Видаліть inherit з model.

Ця функція видаляє всі поля, успадковані через inherit з model та всіх його похідних моделей. Всі поля з успадкованих моделей, включаючи ті, що належать до батьківських моделей, також видаляються, якщо не встановлено режим with_inherit_parents. У такому випадку видаляються тільки поля з inherit, за винятком полів у батьківських моделях. Поля, перелічені в keep, ніколи не видаляються. Якщо деякі нащадки з model перелічені в skip_inherit, вони збережуть поля з inherit.

Параметри
  • model (str) – назва моделі, з якої потрібно видалити успадкування

  • inherit (str) – назва успадкованої моделі (або міксину), яку потрібно видалити

  • keep (tuple(str)) – кортеж із іменами полів, які потрібно зберегти

  • skip_inherit (tuple(str)) – список моделей-нащадків model, які не потрібно обробляти

  • with_inherit_parents (boolean) – якщо не встановлено, видаляти поля лише з inherit, зберігаючи всі поля від батьківських елементів

  • skip_update_references (tuple(str) or "*") – назви полів, посилання на які не потрібно оновлювати під час видалення. Використовуйте "*" для всіх полів.

remove_model(cr, model, drop_table=True, ignore_m2m=())[source]

Видалити модель та її посилання з бази даних.

Деякі обов’язкові непрямі посилання на модель замінюються на невідому модель - порожню модель, яка слугує заповнювачем для зниклих моделей.

Параметри
  • model (str) – назва моделі, яку потрібно видалити

  • drop_table (bool) – чи слід видаляти таблицю цієї моделі

  • ignore_m2m (list(str) or str) – список таблиць m2m, які потрібно ігнорувати - не видаляється, використовуйте "*", щоб ігнорувати (зберегти) всі таблиці m2m

rename_model(cr, old, new, rename_table=True, ignored_m2ms='ALL_BEFORE_18_1')[source]

Перейменування моделі.

Оновлює всі посилання на назву моделі в базі даних.

Якщо запитується перейменування таблиці, починаючи з saaas~18.1+, таблиці m2m також оновлюються, якщо їх не ігнорувати. У старіших версіях таблиці m2m пропускаються, якщо не передається порожній список.

Параметри
  • old (str) – назва поточної моделі

  • new (str) – нова назва моделі

  • rename_table (bool) – чи також перейменувати таблицю моделі

  • ignored_m2ms – таблиці m2m, які потрібно пропустити. За замовчуванням використовується значення "ALL_BEFORE_18_1", що пропускає всі в Odoo 18 або старішій версії, жодні в saa~18.1+. Для всіх версій, якщо значення не є значенням за замовчуванням, пропускаються лише вказані таблиці m2m.

Поля

Функції утиліти для зміни полів моделі.

Виїздні операції найкраще виконувати в скрипті pre- відповідних модулів. У деяких випадках попередню операцію можна виконати в pre, а завершити в post. Типовим прикладом є видалення поля в pre із збереженням його стовпця, який згодом використовується в post, коли стовпець остаточно видаляється.

change_field_selection_values(cr, model, field, mapping, skip_inherit=())[source]

Замінити посилання на значення поля вибору.

Ця функція замінює всі посилання на значення вибору відповідно до зіставлення. Домени також оновлюються.

Параметри
  • model (str) – назва моделі поля вибору, яке потрібно оновити

  • field (str) – назва поля вибору, яке потрібно оновити

  • mapping (dict) – значення вибору для оновлення, ключові значення замінюються відповідними значеннями у відповідності

  • skip_inherit (list(str) or str) – список успадкованих моделей, які потрібно пропустити під час оновлення значень вибору, використовуйте "*", щоб пропустити всі

convert_m2o_field_to_m2m(cr, model, field, new_name=None, m2m_table=None, col1=None, col2=None)[source]

Перетворити поле типу Many2one на поле типу Many2many.

Це створює таблицю зв’язків та заповнює її.

Параметри
  • model (str) – назва моделі поля для перетворення

  • field (str) – поточна назва поля для перетворення

  • new_name (str) – нова назва поля для конвертації. Якщо не вказано, це буде field з завершальною літерою «s».

  • m2m_table (str) – назва таблиці зв’язків. Автоматично генерується, якщо не вказано.

  • col1 (str) – назва стовпця, що посилається на model.

  • col2 (str) – назва стовпця, що посилається на ціль field.

dump_field_to_chatter(cr, model, field, res_id='id', res_model=None, label='%s', fk_display=None, fallback_column=None, where=None, html_escape=True, message_type='notification', subtype_xmlid=None)[source]

Post a chatter message on each record to preserve a column value before it is dropped.

This is useful when a field is being removed during a migration but clients may need to recover its values. The value is posted as a mail_message on the record’s chatter.

If the mail module is not installed (no mail_message table), the value is dumped into fallback_column when one is provided, otherwise the function silently does nothing.

Example

# Simple varchar column
util.dump_field_to_chatter(
    cr, "crm_lead", "mobile", label="Previous Mobile", where="{0}.phone != {0}.mobile"
)

# Drop team_id, save the team name
util.dump_field_to_chatter(
    cr, "res_partner", "team_id", label="Former Sales Team", fk_display="name"
)

# Dump from hr_version onto hr_employee's chatter
util.dump_field_to_chatter(
    cr, "hr_employee", "current_version_id", label="SSN", fk_display="ssnid"
)

# Raw HTML body (no label prefix)
util.dump_field_to_chatter(
    cr, "hr_employee", "notes", html_escape=False,
    message_type="comment", subtype_xmlid="mail.mt_note"
)
Параметри
  • model (str) – model of the field to dump

  • field (str) – field whose value to preserve

  • label (str) – message format. Any valid PG format string with a single %s is allowed. If %s is missing, : %s is appended automatically. Default "%s" produces the raw value with no prefix.

  • res_id (str) – column that identifies the id of the record to put in the chatter.

  • res_model (str or None) – model of the record to post in the chatter, by default it is inferred from res_id target.

  • fk_display (str or None) – when column is a foreign key, the column from the FK target table to use as display value (e.g. "name"). The FK target table is auto-detected. When omitted, only the id is shown. The id is always appended in parentheses.

  • fallback_column (str or None) – column on the same table to dump the value into when the mail module is not installed (no mail_message table). The column must exist (e.g. res_partner.comment), raises otherwise. Translated (jsonb) columns are written through their en_US key.

  • where (str) – extra SQL WHERE condition on the source records. It is a str.format template whose {0} is the source table alias; use it to qualify every column reference, e.g. where="{0}.phone != {0}.mobile". By default, only rows where the dumped column is not NULL (and not empty for text types) are included.

  • html_escape (bool) – whether to HTML-escape the value (default True).

  • message_type (str) – mail_message.message_type (default "notification").

  • subtype_xmlid (str) – optional XML ID for the message subtype (e.g. "mail.mt_note").

invert_boolean_field(cr, model, old, new, skip_inherit=())[source]

Перейменувати логічне поле та інвертувати його значення.

make_field_non_stored(cr, model, field, selectable=False)[source]

Перетворити поле на non-stored.

Параметри
  • model (str) – назва моделі поля для перетворення

  • fieldname (str) – назва поля для конвертації

  • selectable (bool) – чи поле все ще можна вибрати, якщо True користувацькі ir.filters не оновлюються

move_field_to_module(cr, model, fieldname, old_module, new_module, skip_inherit=())[source]

Переміщення поля з одного модуля до іншого.

Ця функція оновлює всі посилання на певне поле, перемикаючись з вихідного модуля на цільовий. Це запобігає видаленню даних після повного завантаження реєстру. Поля в успадковуваних моделях також переміщуються, якщо їх не пропускати.

Параметри
  • model (str) – назва власника моделі поля для переміщення

  • fieldname (str) – назва поля для переміщення

  • old_module (str) – назва вихідного модуля, з якого переміщується поле

  • new_module (str) – назва цільового модуля, в який переміщується поле

  • skip_inherit (list(str) or str) – список моделей-успадкувань, для яких поле не потрібно переміщувати, використовуйте "*", щоб пропустити всі

remove_field(cr, model, fieldname, cascade=False, drop_column=True, skip_inherit=(), keep_as_attachments=False, update_references=True)[source]

Видалити поле та посилання на нього з бази даних.

Ця функція також видаляє поле з моделей, що успадковуються, якщо винятки не вказані в skip_inherit. Коли поле зберігається, ми можемо вибрати, щоб стовпець не видалявся.

Параметри
  • model (str) – назва моделі поля, яке потрібно видалити

  • fieldname (str) – назва поля, яке потрібно видалити

  • cascade (bool) – чи видаляються стовпці поля в режимі CASCADE

  • drop_column (bool) – чи стовпець поля видалено

  • skip_inherit (list(str) or str) – список моделей-успадкувань, щоб пропустити видалення поля, використовуйте "*", щоб пропустити всі

  • keep_as_attachments (bool) – для бінарних полів, чи слід зберігати дані як вкладення

  • update_references (bool) – чи оновлювати всі посилання. Якщо False, не оновлювати дашборд, фільтри, шляхи експорту, домени та зв’язки для пов’язаних полів.

rename_field(cr, model, old, new, update_references=True, domain_adapter=None, skip_inherit=())[source]

Перейменувати поле та його посилання зі old на new у заданій model.

Поле оновлюється у всіх успадковуваних моделях, окрім моделей, зазначених у skip_inherit.

Ця функція також оновлює посилання, прямі чи непрямі, включаючи фільтри, дії сервера, пов’язані поля, електронні листи, інформаційні панелі, домени тощо. Див. update_field_usage()

Для оновлення доменів можна використовувати спеціальну функцію адаптера. Адаптер за замовчуванням просто замінює old на new у кожному листку домену. Зверніться до adapt_domains() для отримання інформації про адаптери доменів.

Параметри
  • model (str) – назва моделі поля, яке потрібно перейменувати

  • old (str) – поточна назва поля, яке потрібно перейменувати

  • new (str) – нова назва поля для перейменування

  • update_references (bool) – чи оновлювати всі посилання

  • domain_adapter (function) – адаптер для використання з доменами, див. adapt_domains()

  • skip_inherit (list(str) or str) – моделі, які потрібно пропустити під час перейменування поля в успадковуваних моделях, використовуйте "*", щоб пропустити всі

update_field_usage(cr, model, old, new, domain_adapter=None, skip_inherit=())[source]

Замініть усі посилання на поле old на new у різних місцях.

Пошук у:
  • ir_filters

  • ir_exports_line

  • ir_act_server

  • mail_alias

  • ir_ui_view_custom (інф. панель)

  • sign_item_type

  • sign_item

  • домени (за допомогою domain_adapter)

  • пов’язані поля

Ця функція може бути використана для заміни використання одного поля іншим. Домени оновлюються за допомогою domain_adapter. За замовчуванням адаптер домену просто замінює old на new у листі домену. Дивіться adapt_domains() для отримання додаткової інформації про адаптери домену.

Параметри
  • model (str) – назва моделі поля

  • old (str) – вихідна назва поля, яке потрібно замінити

  • new (str) – цільова назва поля, яку потрібно встановити

  • domain_adapter (function) – адаптер для використання з доменами, див. adapt_domains()

  • skip_inherit (list(str) or str) – моделі, які потрібно пропустити під час перейменування поля в успадковуваних моделях, використовуйте "*", щоб пропустити всі

Запис

Функції утиліти для операцій на рівні записів.

delete_unused(cr, *xmlids, **kwargs)[source]

Видаліть невикористані записи.

Ця функція видалятиме записи, на які вказує xmlids, лише якщо на них немає посилання з жодної таблиці. Для ієрархічних записів (наприклад, категорій продуктів) вона перевіряє, чи немає посилання на дочірні записи, позначені як каскадне видалення. У такому разі запис та його дочірні елементи видаляються.

Примітка

Записи, які не можна видалити, встановлюються як noupdate=True.

Параметри
  • xmlids (list(str)) – список xml_ids для перевірки на видалення

  • deactivate (bool) – чи деактивувати записи, які неможливо видалити, оскільки на них є посилання, за замовчуванням False

  • keep_xmlids (bool) – чи зберігати xml_ids записів, які не можна видалити. За замовчуванням True для версій до 18.0, False починаючи з saas~18.1.

  • include_m2m (list(str) or str) – list of m2m tables to include in the search. "*" for all.

Повертає

список ідентифікаторів видалених записів, якщо такі є

Тип повернення

list(int)

edit_view(cr, xmlid=None, view_id=None, skip_if_not_noupdate=True, active='auto')[source]

Менеджер контексту для редагування arch представлення.

Ця функція повертає контекстний менеджер, який може повернути розібрану структуру представлення як etree Element. Будь-які зміни, зроблені в поверненому об’єкті, будуть записані назад у базу даних після виходу з контекстного менеджера, оновлюючи також перекладені версії структури. Оскільки функція може не повертати результат, використовуйте skippable_cm(), щоб уникнути помилок.

with util.skippable_cm(), util.edit_view(cr, "xml.id") as arch:
    arch.attrib["string"] = "My Form"

Щоб вибрати цільове представлення для редагування, використовуйте або xmlid, або view_id, а не обидва одночасно.

Коли вид ідентифікується за допомогою view_id, arch завжди передається, якщо представлення існує, незважаючи на будь-який прапор noupdate, який може бути з ним пов’язаний. Коли встановлено xmlid, якщо прапор noupdate представлення має значення False, arch не буде передана, якщо skip_if_not_noupdate не встановлено на False. Якщо noupdate має значення True, представлення буде передано для редагування.

Якщо аргумент active має значення True або False, прапорець active представлення буде встановлено відповідно.

Примітка

Якщо active має значення «автоматично» (значення за замовчуванням), представлення буде активоване, якщо вибрано через xmlid, і залишиться незмінним, якщо вибрано через view_id.

Параметри
  • xmlid (str) – необов’язково, xml_id редагування представлення

  • view_id (int) – необов’язково, ID представлення даних для редагування

  • skip_if_not_noupdate (bool) – чи слід примусово редагувати представлення, запитувані через параметр xmlid, навіть якщо вони позначені як noupdate=True, ігнорується, якщо встановлено view_id

  • active (bool or None or "auto") – значення активного прапорця, яке потрібно встановити. Не змінюється, якщо None.

Повертає

менеджер контексту, який видає проаналізовану арку, після виходу менеджер контексту записує зміни назад.

ensure_xmlid_match_record(cr, xmlid, model, values)[source]

Переконайтеся, що xml_id посилається на запис із певними значеннями.

Ця функція гарантує, що запис, на який вказує xml_id, відповідає значенням для полів, зазначених у параметрі values. Коли xmlid існує, але вказує на запис, який не відповідає значенням, xmlid оновлюється, щоб вказувати на запис, який відповідає значенням, якщо такий знайдено. Якщо xmlid не існує, він створюється зі знайденим записом. Якщо відповідний запис не знайдено, нічого не робиться. У всіх випадках повертається запис, на який посилається, після можливого оновлення xml_id.

Параметри
  • xmlid (str) – запис xml_id у форматі module.name

  • model (str) – назва моделі запису

  • values (dict) – зіставлення назв полів зі значеннями, яким має відповідати запис .. example:: .. code-block:: python values = {«id»: 123} values = {«name»: «INV/2024/0001», «company_id»: 1}

Повертає

ідентифікатор запису, що відповідає значенню, None, якщо запис не знайдено

Тип повернення

int or None

Порада

Ця функція корисна під час міграції записів з бази даних у користувацький модуль, щоб створити xml_ids перед оновленням модуля та уникнути дублювання.

force_noupdate(cr, xmlid, noupdate=True, warn=False)[source]

Оновити прапорець noupdate запису.

Параметри
  • xmlid (str) – запис xml_id у форматі module.name

  • noupdate (bool) – значення, яке потрібно встановити для прапорця noupdate

  • warn – чи виводити попередження в журнали, коли прапорець було змінено з True на False

if_unchanged(cr, xmlid, callback, interval='1 minute', **kwargs)[source]

Виконати callback, якщо запис не змінився.

Ця функція запустить callback, коли зазначений запис не змінився. xmlid та будь-які додаткові параметри, крім interval, будуть передані до callback. У разі зміни запису він буде позначений як noupdate=True. Див. також is_changed() та force_noupdate().

Ця функція корисна для виконання дії тільки, коли запис не було оновлено. Типовим прикладом є примусове оновлення з XML, навіть якщо запис мав значення noupdate=True.

util.if_unchanged(cr, "mymodule.myrecord", util.update_record_from_xml)
Параметри
  • xmlid (str) – xml_id запису для перевірки

  • callback (function) – зворотний виклик для виконання у випадку, якщо запис не було змінено, всі додаткові параметри цієї функції передаються до зворотного виклику

  • interval (str) – інтервал після create_date, у який запис вважається _changed_, див. is_changed()

is_changed(cr, xmlid, interval='1 minute')[source]

Повертає інформацію про те, чи було змінено запис.

Ця функція перевіряє, чи запис було змінено до поточного часу початку оновлення. Див. upgrade-util/src/base/0.0.0/pre-00-upgrade-start.py

Ця утиліта повертатиме хибнопозитивний результат для xmlid записів, які відповідають таким умовам:

  • Були оновлені в оновленні, що передувало поточному

  • Не оновлювалися в поточному оновленні

Якщо xmlid не існує в базі даних, ця функція повертає None.

Параметри
  • xmlid (str) – xmlid запису для перевірки

  • interval (str) – Інтервал SQL, запис вважається зміненим, якщо write_date > create_date + interval

Тип повернення

bool or None

ref(cr, xmlid)[source]

Повертає id, що відповідає заданому xml_id.

Параметри

xml_id (str) – запис xml_id у форматі module.name

Повертає

ID запису, на який посилаються, None, якщо не знайдено.

Тип повернення

int or None

refs(cr, xmlids, strict=False)[source]

Return a mapping of xmlid -> res_id for the given list of xmlids.

Параметри
  • xmlids (list) – list of fully qualified xml_ids, each under the format module.name

  • strict (bool) – if True, only include xmlids that exist in the database.

Повертає

dict mapping each xmlid to its res_id; missing xmlids map to None unless strict=True, in which case they are omitted from the result.

Тип повернення

dict

remove_record(cr, name)[source]

Видалити запис та посилання на нього, що відповідають заданому xml_id.

Параметри

name (str) – запис xml_id у форматі module.name

remove_view(cr, xml_id=None, view_id=None, silent=False, key=None)[source]

Видалити представлення та всіх його нащадків.

Ця функція рекурсивно видаляє вказаний вигляд та його успадковані вигляди, якщо вони входять до складу модуля. Вона також видаляє вигляди COWed, що використовуються на кількох веб-сайтах.

Параметри
  • xml_id (str) – необов’язково, xml_id представлення, яке потрібно видалити

  • view_id (int) – необов’язково, ID представлення, яке потрібно видалити

  • silent (bool) – чи показувати в журналах вимкнені користувацькі представлення

  • key (str or None) – ключ, що використовується для виявлення представлень COW з кількох веб-сайтів. Якщо значення None, тоді значення xml_id, якщо воно надано, інакше значення xml_id, що посилається на перегляд з ID view_id, якщо такий є.

Попередження

Потрібно встановити або xml_id, або view_id. Вказівка обох призведе до помилки.

Порада

Якщо потрібно видалити кілька переглядів, скористайтеся функцією remove_views() - вона виконує ресурсомісткі операції пакетно:

util.remove_views(cr, "module.view_one", "module.view_two")
remove_views(cr, *xml_ids, **kwargs)[source]

Видалити кілька переглядів та всі їхні дочірні елементи.

Ця функція видаляє вказані перегляди та їхні успадковані перегляди, якщо вони входять до складу модуля. Вона також видаляє перегляди COWed, що використовуються на кількох веб-сайтах. Те, чи будуть дочірні або COWed-перегляди видалені чи лише вимкнені, визначається пов’язаним з ними xml_id; перегляд, що належить до модуля, видаляється, а визначений користувачем - вимикається.

Параметри

xml_ids (str) – xml_ids переглядів, які потрібно видалити

rename_xmlid(cr, old, new, noupdate=None, on_collision='fail')[source]

Перейменувати external identifier (xml_id) запису.

Перейменування неможливе, якщо цільова назва вже існує в базі даних. У таких випадках є два варіанти керування поведінкою цієї функції:

  • fail: викликати виняток та запобігти перейменуванню

  • merge: перейменувати зовнішній ідентифікатор, видалити старий та замінити посилання. Див. replace_record_references_batch()

Примітка

Ця функція не видаляє записи, вона лише оновлює xml_ids.

Параметри
  • old (str) – поточний xml_id запису у форматі module.name

  • new (str) – новий xml_id запису у форматі module.name

  • noupdate (bool or None) – значення, яке потрібно встановити для прапорця noupdate xml_id, ігнорується, якщо None

  • on_collision (str) – як діяти далі, якщо xml_id вже існує, варіанти: merge або fail (за замовчуванням)

Повертає

ID запису, на який посилається новий xml_id, None, якщо запис не існує

Тип повернення

int or None

replace_in_all_jsonb_values(cr, table, column, old, new, extra_filter=None)[source]

Замінити значення у колонках JSONB.

Ця функція замінює old на new у значеннях JSONB. Вона корисна для заміни значень у всіх перекладах перекладених полів.

Параметри
  • table (str) – назва таблиці, де потрібно замінити значення

  • column (str) – назва колонки, де потрібно замінити значення

  • old (str) – початкове значення для заміни може бути простим терміном (str) або регулярним виразом Postgres, обгорнутим PGRegexp

  • new (str) – нове значення, яке потрібно встановити, може бути простим терміном або виразом з використанням нотації <number> для позначення захоплених груп, якщо old є регулярним виразом

  • extra_filter (str) – додатковий сумісний з WHERE пункт для фільтрації значень для оновлення, необхідно використовувати алыас t для таблиці, він також може включати {parallel_filter} для паралельного виконання запиту, див. explode_execute()

replace_record_references_batch(cr, id_mapping, model_src, model_dst=None, replace_xmlid=True, ignores=(), parent_field='parent_id')[source]

Замініть усі посилання на записи.

Ця функція замінює всі посилання, прямі чи непрямі, на записи model_src відповідними записами у відображенні. Якщо цільова модель відображення відрізняється від вихідної, тоді необхідно встановити параметр model_dst.

Параметри
  • id_mapping (dict(int, int)) – зіставлення ідентифікаторів для заміни, значення ключа замінюється зіставленим значенням

  • model_src (str) – назва вихідної моделі записів, які потрібно замінити

  • model_dst (str) – назва цільової моделі записів, які потрібно замінити; якщо None, ціль вважається такою ж, як і джерело

  • replace_xmlid (bool) – чи замінювати посилання в xml_ids, що вказують на вихідні записи

  • ignores (list(str)) – список назв**таблиць**, які потрібно пропустити під час оновлення значень, на які посилаються

Paream str parent_field

Коли цільова та вихідна моделі однакові, і таблиця моделі має стовпець parent_path, це поле буде використано для її оновлення.

update_record_from_xml(cr, xmlid, reset_write_metadata=True, force_create=AUTO, from_module=None, reset_translations=(), ensure_references=False, fields=None)[source]

Оновити запис на основі його визначення у файлі Файли даних.

Ця функція ігнорує прапорець noupdate у записі. Вона шукає відповідне визначення у всіх XML-файлах з маніфесту модуля в xmlid або в параметрі from_module, якщо він встановлений. Знайшовши його, вона змушує ORM оновити запис, як зазначено у специфікаціях у файлі даних.

За бажанням, ця функція може скинути переклади деяких полів.

Параметри
  • xmlid (str) – запис xml_id у форматі module.name

  • reset_write_metadata (bool) – чи оновлювати write_date запису

  • force_create (bool) – чи створюється запис, якщо його не існує. За замовчуванням значення True, якщо fields не дорівнює None.

  • from_module (str) – назва модуля, з якого оновлюється запис, необхідна лише тоді, коли специфікації знаходяться в іншому модулі, ніж той, що в xml_id

  • reset_translations (set(str)) – назви полів, переклади яких скидаються

  • ensure_references (bool) – чи слід також оновлювати записи, на які посилаються через атрибути XML ref.

  • fields (set(str) or None) – необов’язковий список полів для включення до XML-оголошення. Якщо встановлено, всі інші поля будуть ігноруватися. Якщо встановлено, запис не буде створено, якщо його немає, а всі поля, які не знайдено в XML-оголошенні, будуть встановлені на NULL/за замовчуванням.

Попередження

Ця функція використовує ORM, тому її можна використовувати лише після того, як всі моделі, на які посилаються в специфікаціях даних запису, вже завантажені. На практиці це означає, що цю функцію слід використовувати в скриптах post- або end-.

Примітка

Стандартна поведінка ORM полягає у створенні запису, якщо він не існує, включаючи його xml_id. Це також станеться в цій функції, якщо тільки для force_create не встановлено значення False.

ORM

Допоміжні функції для виконання операцій через ORM.

Функції цього модуля дозволяють безпечно використовувати ORM під час оновлень. Вони покращують або виправляють ORM таким чином, щоб він міг ефективно обробляти великі обсяги даних. У деяких випадках надаються повністю альтернативні функції до власних функцій ORM. Функції цього модуля працюють з ORM всіх підтримуваних версій.

env(cr)[source]

Створіть нове середовище.

Попередження

Ця функція не очищує кеш, що зберігається на курсорі для суперкористувача з порожнім середовищем. Виклик invalidate_cache може знадобитися щоразу, коли дані змінюються безпосередньо в базі даних.

Повертає

нове середовище

Тип повернення

Environment

get_inherit_model_names(model)[source]

Get the names of the models the model directly or indirectly _inherit.

Параметри

model – recordset

Повертає

the names of the models the model directly or indirectly _inherit. If model._name is not in the returned set, the model is defined once. base is always in the returned set for non-base models.

Тип повернення

list[str]

class iter_browse(model, *args, **kw)[source]

Ітерація понад наборів записів.

Об’єкт callable, що повертається цим класом, можна використовувати як ітератор, який завантажує записи фрагментами (у recordset). Після вичерпання кожного фрагмента його дані надсилаються назад до бази даних (очищаються або фіксуються) і завантажується новий фрагмент.

Цей клас дозволяє виконувати код, подібний до:

for record in env['my.model'].browse(ids):
    record.field1 = val

env['my.model'].browse(ids)._compute_field2()
env['my.model'].create(values)

продуктивним способом, водночас уникаючи MemoryError, навіть коли ids або values мають мільйони записів. Альтернативою використання цього класу буде:

Example

MyModel = util.env(cr)['my.model']
for record in util.iter_browse(MyModel, ids):
    record.field1 = val

util.iter_browse(MyModel, ids)._compute_field2()
util.iter_browse(MyModel, ids).create(values)
Параметри
  • model (odoo.model.Model) – модель для ітерації

  • ids (iterable(int)) – iterable of IDs of the records to iterate

  • size (int) – the length of ids. Can be used to enable progress logging when ids has no __length__

  • query (str) – alternative to ids, SQL query that can produce them. Can also be a DML statement with a RETURNING clause. See query_ids()

  • chunk_size (int) – кількість записів для завантаження в кожному фрагменті ітерації, за замовчуванням 200

  • yield_chunks (bool) – when iterating, yield records in chunks of chunk_size instead of one by one. Default is False

  • logger (logging.Logger) – логер, який використовується для звітування про прогрес, за замовчуванням _logger

  • strategy (str) – чи потрібно flush, чи commit для кожного фрагмента, за замовчуванням flush

Повертає

об’єкт, що повертається цим класом, можна використовувати для ітерації або безпечного виклику будь-якого методу моделі на мільйонах записів.

Див. також env()

create(values=None, query=None, **kw)[source]

Створюйте записи.

Альтернатива методу create за замовчуванням в ORM, яку безпечно використовувати для створення мільйонів записів.

Параметри
  • values (iterable(dict)) – iterable of values of the records to create

  • size (int) – the no. of elements produced by values or query. Can be used to enable progress logging when ids has no __length__ or with query

  • query (str) – alternative to values, SQL query that can produce them. Can also be a DML statement with a RETURNING clause.

  • multi (bool) – чи використовувати багатофункціональну версію create, за замовчуванням True з Odoo 12 і вище

recompute_fields(cr, model, fields, ids=None, logger=<Logger odoo.upgrade.util.orm (WARNING)>, chunk_size=256, strategy='auto', query=None)[source]

Переобчислити значення полів.

Ця функція перераховує поля моделі, обмежені набором записів - або всіма. Перерахунок не виконується одночасно для всіх записів. Він розділений на партії (блоки). Це дозволяє уникнути проблем з продуктивністю і, в гіршому випадку, збоїв через MemoryError. Після обробки кожного блоку дані відправляються назад до бази даних відповідно до однієї з наступних стратегій:

  • flush: використовувати метод flush ORM

  • commit: commit курсор - також скинути

  • auto: вибрати найкращий варіант між двома вищезазначеними, враховуючи кількість записів для обчислення та наявність відстежуваних полів.

Стратегія commit менш схильна до виникнення помилки MemoryError для величезного обсягу даних.

Параметри
  • model (str) – назва моделі для переобчислення

  • fields (list(str)) – список назв полів для переобчислення

  • ids (list(int) or None) – список ідентифікаторів записів для переобчислення, коли None переобчислює всі записи, якщо також не встановлено query (див. нижче)

  • logger (logging.Logger) – логер, який використовується для звітування про прогрес

  • chunk_size (int) – кількість записів на фрагмент – використовується для розділення обробки

  • strategy (str) – стратегія, що використовується для обробки перерахунку

  • query (str) – запит на отримання IDs записів для переобчислення, встановлення одночасно ids та query є помилкою. Зверніть увагу, що обробка завжди відбуватиметься у порядку зростання. Якщо це небажано, замість цього потрібно використовувати ids.

adapt_domains(cr, model, old, new, adapter=None, skip_inherit=(), force_adapt=False)[source]

Замініть old на new в доменах, використовуючи model та успадковуючи моделі.

adapter - це функція зворотного виклику для адаптації листя. Функції адаптера повинні приймати три аргументи та повертати domain, який замінює оригінальне листя. Аргументи:

  • leaf: лист домену, який є tuple виду (left, op, right)

  • in_or: логічне значення, коли True означає, що лист є частиною домену АБО ("|"), інакше він є частиною домену І ("&").

  • negated: логічне значення, коли True означає, що листок заперечений ("!")

Example

def adapter(leaf, in_or, negated):
    left, op, right = leaf
    ok, ko = (1, 2) if not negated else (2, 1)
    if op == "="
        return [(left, "=", ok)]
    elif op == "!=":
        return [(left, "=", ko)]
    return [leaf]

adapter викликається лише на листках, які використовують поле old model як остання частину left частини leaves, якщо force_adapt не має значення True. В останньому випадку адаптер викликається, якщо поле з’являється будь-де в шляху, що корисно лише для реляційних полів.

У доменах, що повертаються адаптером, не потрібно замінювати поле old на new у лівій частині вхідного аркуша. Заміна все одно буде виконана для всього домену, що повертається адаптером. Звичайне призначення adapter - змінити оператор та праву частину вхідного аркуша. Якщо adapter не встановлено, відбувається лише заміна.

Example

Під час заміни "field1" на "field2" відбувається наступне:

  • ("foo.bar.baz.field1", "=", 1) адаптується тільки, якщо запис, на який вказує foo.bar.baz, належить до запитуваної моделі.

  • ("foo.field1.baz", "=", 1) не адаптується навіть якщо foo вказує на model, окрім випадків, коли force_adapt має значення True, оскільки field1 не є останньою частиною left у цьому листі.

Примітка

Ця функція замінить домени у всіх стандартних полях доменів. Включно з фільтрами, інформаційними панелями та стандартними полями, які, як відомо, представляють домен.

Параметри
  • model (str) – назва моделі, для якої потрібно адаптувати домени

  • old (str) – назва поля, яке потрібно адаптувати

  • new (str) – назва поля, яке має замінити old

  • adapter (function) – адаптер для відпусток

  • skip_inherit (list(str)) – список успадкованих назв моделей, які не потрібно адаптувати (пропустити)

  • force_adapt (bool) – якщо True, запускати adapter на всіх листках, що мають new у лівій частині листка (шляху), корисно під час видалення поля (у цьому випадку new ігнорується).

SQL

Функції утилыти для взаємодії з PostgreSQL.

class ColumnList(list_=(), quoted=())[source]

Інкапсулюйте список елементів, що представляють назви стовпців.

Результуючий об’єкт можна відобразити як рядок з початковою/кінцевою комою або аліасом.

Параметри
  • list (list(str)) – список назв колонок

  • quoted (list(str)) – список назв колонок у лапках, він має відповідати параметру list_

Example

>>> columns = ColumnList(["id", "field_Yx"], ["id", '"field_Yx"'])
>>> list(columns)
['id', '"field_Yx"']
>>> columns.using(alias="t").as_string(cr._obj)
'"t"."id", "t"."field_Yx"'
>>> columns.using(leading_comma=True).as_string(cr._obj)
', "id", "field_Yx"'
>>> util.format_query(cr, "SELECT {} t.name FROM table t", columns.using(alias="t", trailing_comma=True))
'SELECT "t"."id", "t"."field_Yx", t.name FROM table t'
>>> columns = ColumnList.from_unquoted(cr, ["foo", "BAR"])
>>> list(columns)
['"foo"', '"BAR"']
>>> list(columns.iter_unquoted())
['foo', 'BAR']

Примітка

Цей клас краще використовувати через get_columns()

classmethod from_unquoted(cr, list_)[source]

Створіть ColumnList зі списку назв колонок, які можуть потребувати лапок.

Параметри

list (list(str)) – список назв колонок без лапок

using(leading_comma=KEEP_CURRENT, trailing_comma=KEEP_CURRENT, alias=KEEP_CURRENT)[source]

Налаштуйте параметри для відображення цього списку у вигляді рядка.

Параметри
  • leading_comma (bool) – чи відображати кому на початку цього списку

  • trailing_comma (bool) – чи відображати кінцеву кому

  • alias (str or None) – аліас таблиці колонок, аліас не додається, якщо встановлено значення None

Повертає

копія списку із заданими параметрами

Тип повернення

ColumnList

iter_unquoted()[source]

Перебираємо ітерації по необроблених назв колонок, без лапок.

Це корисно, якщо цитування виконується поза цим об’єктом. Також для отримання доступу до необроблених назв колонок, як у каталозі Postgres.

Повертає

ітератор для необроблених назв колонок

class PGRegexp[source]

Обгортка для семантичного значення параметрів: цей рядок є регулярним виразом Postgres.

Див. replace_in_all_jsonb_values()

class SQLStr[source]

Обгортка для семантичного значення параметрів: цей рядок є коректним фрагментом SQL.

Див. format_query()

alter_column_type(cr, table, column, type, using=None, where=None, logger=<Logger odoo.upgrade.util.pg (WARNING)>)[source]

Змінити тип колонки.

Зробіть це ефективно, використовуючи тимчасову колонку та паралельні запити UPDATE.

Параметри
  • table (str) – назва відповідної колонки.

  • column (str) – назва колонки, тип якого потрібно змінити.

  • type (str) – новий тип колонки.

  • using (str) – SQL-вираз, що визначає, як конвертувати значення в новий тип. Заповнювач {0} буде замінено назвою стовпця.

  • where (str) – використовується для обмеження значень, перетворених за допомогою using.

  • logger (logging.Logger) – логер, який використовується для звітування про прогрес.

bulk_update_table(cr, table, columns, mapping, key_col='id')[source]

Оновити таблицю на основі зіставлення.

Кожен запис mapping визначає нові значення для вказаних стовпців для рядка(ів), значення key_col яких відповідає ключу.

Example

# single column update
util.bulk_update_table(cr, "res_users", "active", {42: False, 27: True})

# multi-column update
util.bulk_update_table(
    cr,
    "res_users",
    ["active", "password"],
    {
        "admin": [True, "1234"],
        "demo": [True, "5678"],
    },
    key_col="login",
)
Параметри
  • table (str) – таблиця для оновлення.

  • columns (str | list(str)) – cпецифікація стовпців для оновлення. Це може бути назва одного стовпця або список назв стовпців. mapping має відповідати специфікації.

  • mapping (dict) – значення, які потрібно встановити, і які мають відповідати специфікації в columns, дотримуючись того самого порядку

  • key_col (str) – стовпець, який використовується як ключ для отримання значень з mapping під час оновлення.

Попередження

Значення у мапінгу будуть приведені до типу цільового стовпця. Ця функція призначена для оновлення скалярних значень, щоб уникнути встановлення масивів або JSON-даних через мапінг.

column_exists(cr, table, column)[source]

Повертає інформацію про існування колонки.

Параметри
  • table (str) – таблиця для перевірки

  • column (str) – колонка для перевірки

Тип повернення

bool

column_type(cr, table, column, sized=False)[source]

Повертає тип колонки, якщо він існує.

Параметри
  • table (str) – таблиця для перевірки

  • column (str) – колонка для перевірки

Тип повернення

SQL type of the column

copy_column(cr, table, column, new_name=AUTO)[source]

Copy a column.

This function copies a column if it exists. It raises an error otherwise.

Параметри
  • table (str) – table of the column

  • column (str) – name of the column

  • new_name (str) – name of the new column, if not passed the original column name will be used with suffix _upg_copy.

Повертає

new column name

Тип повернення

str

create_column(cr, table, column, definition, **kwargs)[source]

Створити колонку.

Ця функція створить колонку тільки в тому випадку, якщо він не існує. Вона зареєструє помилку, якщо існуюча колонка має інший тип. Якщо встановлено fk_table, вона забезпечить налаштування зовнішнього ключа, оновлюючи його за необхідності, з правильним on_delete_action, якщо такий встановлено.

Параметри
  • table (str) – таблиця нової колонки

  • column (str) – назва нової колонки

  • definition (str) – column type of the new column. Use AUTO to infer the type from the id column of fk_table.

  • default (bool) – значення за замовчуванням, яке потрібно встановити для нової колонки

  • fk_table (str) – if the new column is a foreign key, name of the foreign table

  • on_delete_action (str) – Речення ON DELETE, за замовчуванням NO ACTION, дійсне лише якщо колонка є зовнішнім ключем.

Повертає

чи було створено колонку

Тип повернення

bool

create_m2m(cr, m2m, fk1, fk2, col1=None, col2=None)[source]

Переконайтеся, що таблиця m2m існує або створена.

Ця функція створює таблицю, пов’язану з полем m2m. Якщо таблиця вже існує, для неї виконується fixup_m2m(). Ім’я таблиці може бути згенеровано автоматично, застосовуючи ту саму логіку ORM. Для цього використовуйте значення «auto» для параметра m2m.

Параметри
  • m2m (str) – назва таблиці для створення, якщо AUTO, вона генерується автоматично

  • fk1 (str) – перша назва таблиці зовнішнього ключа

  • fk2 (str) – назва другої таблиці зовнішнього ключа

  • col1 (str) – стовпець, що посилається на fk1, за замовчуванням має значення "{fk1}_id"

  • col2 (str) – стовпець, що посилається на fk2, за замовчуванням має значення "{fk2}_id"

Повертає

назва щойно створеної/виправленої таблиці

Тип повернення

str

explode_execute(cr, query, table, alias=None, bucket_size=10000, logger=<Logger odoo.upgrade.util.pg (WARNING)>, qualifier='queries')[source]

Виконайте запит паралельно.

Запит розділяється на групи ідентифікаторів, а потім обробляється паралельно працівниками. Якщо запит не містить спеціального значення {parallel_filter}, воно додається до останнього оператора WHERE, а також може бути додане, якщо його не знайдено. Якщо запит вже містить фільтр, нічого не робиться. Фільтр завжди розширюється до стратегії розділення. Розділення здійснюється на групи, в яких для кожного окремого запиту оновлюється не більше ніж bucket_size ідентифікаторів.

Example

util.explode_execute(
    cr,
    '''
    UPDATE res_users u
       SET active = False
     WHERE (u.login LIKE 'dummy' OR u.login = 'bob')
       AND {parallel_filter}
    ''',
    table="res_users"
    alias="u",
)
Параметри
  • query (str) – запит для виконання.

  • table (str) – назва головної таблиці запиту, що використовується для розділення обробки

  • alias (str) – аліас, який використовується для головної таблиці в запиті

  • bucket_size (int) – розмір корзин ідентифікаторів для розділення обробки

  • logger (logging.Logger) – логер, який використовується для звітування про прогрес

  • qualifier (str) – qualifier of the queries. Used in the progression log

Повертає

сума cr.rowcount для кожного виконання запиту

Тип повернення

int

Попередження

Користувач, який здійснює виклик, повинен переконатися, що запити не оновлюють одні й ті ж записи в різних сегментах. Не рекомендується використовувати цю функцію для запитів DELETE у таблицях із самопосиланнями через можливі наслідки ON DELETE. Для отримання додаткової інформації див. parallel_execute().

format_query(cr, query, *args, **kwargs)[source]

Безпечно форматуйте запит.

Аргументи str цієї функції вважаються ідентифікаторами SQL. Вони обертаються подвійними лапками перед розгортанням за допомогою str.format(). Також допускаються будь-які інші psycopg2.sql.Composable. Сюди входить ColumnList, див. також get_columns()

Example

>>> util.format_query(cr, "SELECT {0} FROM {table}", "id", table="res_users")
SELECT "id" FROM "res_users"
Параметри

query (str) – запит для форматування, можна використовувати дужки {}, як у str.format()

get_columns(cr, table, ignore=('id',))[source]

Повернути список колонок у таблиці.

Параметри
  • table (str) – назва таблиці, колонки якої отримуються

  • ignore (list(str)) – список назв колонок, які слід ігнорувати у списку повернення

Повертає

список назв колонок, присутніх у таблиці

Тип повернення

ColumnList

get_common_columns(cr, table1, table2, ignore=('id',), type_check=True)[source]

Повернути список колонок, присутніх в обох таблицях.

Параметри
  • table1 (str) – перша назва таблиці, колонки якої отримуються

  • table2 (str) – назва другої таблиці, колонки якої отримуються

  • ignore (list(str)) – список назв колонок, які слід ігнорувати у списку повернення

  • type_check (bool) – повертає лише спільні стовпці з сумісними типами даних

Повертає

список імен стовпців, що містяться в обох таблицях

Тип повернення

ColumnList

get_m2m_on(cr, table)[source]

Return a list of m2m tables associated with table.

We identify as m2m table all tables that have only two columns, both of which are FKs. This function will return m2m tables for which one FK points to table.

Примітка

Таблиці M2M повертаються лише один раз. Незалежно від того, чи для одних і тих самих стовпців визначено кілька зовнішніх ключів, чи обидва стовпці M2M посилаються на table. У другому випадку стовпці повертаються в алфавітному порядку.

Повертає

list of (m2m_table, fk_col_to_table, other_fk_col, other_table) tuples

class named_cursor(cr, itersize=None)[source]

Server side cursor.

This class wraps a psycopg2 server-side cursor. It adds convenient methods like dictfetchmany and dictfetchall. It should be used as a context manager.

Server-side cursors are useful to fetch huge amounts of data from the DB by chunks while at the same time keep using the main upgrade cursor.

Параметри

itersize (int) – determines the number of rows fetched from PG at once.

parallel_execute(cr, queries, logger=<Logger odoo.upgrade.util.pg (WARNING)>, qualifier='queries')[source]

Виконуйте запити паралельно.

Example

util.parallel_execute(cr, [util.format_query(cr, "REINDEX TABLE {}", t) for t in tables])

Порада

Якщо ви хочете пришвидшити виконання одного запиту, дивіться explode_execute().

Параметри
  • queries (list(str)) – список запитів для одночасного виконання

  • logger (Logger) – логер, який використовується для звітування про прогрес

  • qualifier (str) – qualifier of the queries. Used in the progression log

Повертає

сума cr.rowcount для кожного виконання запиту

Тип повернення

int

Попередження

  • Через особливості функції cr.rowcount, значення, яке повертає ця функція, може бути заниженим порівняно з реальним числом записів, на які впливає операція. Наприклад, якщо деякі записи видаляються/оновлюються в результаті використання оператора ondelete, вони не враховуються.

  • Як побічний ефект, курсор буде зафіксовано.

Примітка

Якщо виникне проблема паралельності, невдалі запити будуть повторені послідовно.

class query_ids(cr, query, itersize=None)[source]

Iterator over ids returned by a query.

This allows iteration over a potentially huge number of ids without exhausting memory.

Параметри
  • query (str) – the query that returns the ids. It can be DML, e.g. UPDATE table WHERE ... RETURNING id.

  • itersize (int) – determines the number of rows fetched from PG at once, see named_cursor().

remove_constraint(cr, table, name, cascade=False, warn=True)[source]

Видалити обмеження таблиці.

Ця функція видаляє обмеження name з table. Вона також видаляє записи з ir_model_constraint та його xml_ids. Вона реєструє не знайдені обмеження.

Примітка

Якщо обмеження name відсутнє, ця функція спробує видалити {table}_{name}, останнє є ім’ям за замовчуванням, яке ORM використовує для обмежень, створених з _sql_constraints.

Параметри
  • table (str) – таблиця, з якої видалити обмеження

  • name (str) – назва обмеження, яке потрібно видалити

  • cascade (bool) – каскадне видалення обмежень

  • warn (bool) – використовувати рівень попередження під час реєстрації обмежень, що не знайдено, інакше використовувати рівень інформації

Повертає

чи було знято обмеження

Тип повернення

bool

rename_table(cr, old_table, new_table, remove_constraints=True)[source]

Перейменувати таблицю.

Ця функція перейменовує таблицю old_table на new_table, а також її первинний ключ (та послідовність), індекси та зовнішні ключі.

Параметри
  • old_table (str) – назва таблиці, яку потрібно перейменувати

  • new_table (str) – нова назва таблиці

Para bool remove_constraints

чи слід видаляти обмеження таблиці

Різне

Різні автономні функції.

chunks(iterable, size, fmt=None)[source]

Розділити iterable на фрагменти розміром size та обгорнути кожен фрагмент за допомогою функції fmt.

Ця функція корисна для розділення величезних вхідних даних на менші фрагменти, які можна обробляти незалежно.

Example

>>> list(chunks(range(10), 4, fmt=tuple))
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9)]
>>> ' '.join(chunks('abcdefghijklm', 3))
'abc def ghi jkl m'
Параметри
  • iterable (iterable) – ітерований об’єкт для розділення

  • size (int) – розмір фрагмента

  • fmt (function) – функція, яка застосовується до кожного фрагмента, коли передається None, fmt стає "".join, якщо iterable – це рядок, інакше iter

Повертає

генератор, який перебирає результат fmt, застосований до кожного фрагмента

expand_braces(s)[source]

Розгорнути фігурні дужки у вхідних даних.

Example

>>> util.expand_braces("a_{this,that}_b")
['a_this_b', 'a_that_b']
Параметри

s (str) – рядок, який потрібно розгорнути, повинен містити рівно одну пару фігурних дужок.

Повертає

розширений вхід

import_code_upgrade(name)[source]

Import a code upgrade script.

Allow import of upgrade_code scripts to be used inside upgrade scripts.

Параметри

name (str) – name of the script to import.

import_script(path, name=None)[source]

Імпортуйте скрипт оновлення.

Ця функція дозволяє імпортувати функції з інших скриптів оновлення в поточний.

Example

У mymodule/15.0.1.0/pre-migrate.py

def my_util(cr):
    # do stuff

У myothermodule/16.0.1.0/post-migrate.py

from odoo.upgrade import util

script = util.import_script("mymodule/15.0.1.0/pre-migrate.py")

def migrate(cr, version):
    script.my_util(cr)  # reuse the function

Ця функція повертає модуль Python.

>>> util.import_script("base/0.0.0/end-moved0.py", name="my-moved0")
<module 'my-moved0' from '/home/odoo/src/upgrade-util/src/base/0.0.0/end-moved0.py'>
Параметри
  • path (str) – відносний шлях до скрипта для імпорту у форматі $module/$version/$script-name .. примітка:: скрипт має бути доступний у шляху оновлення.

  • name (str or None) – name to assign to the returned module. When None, a name is derived from path to mirror the name set by Odoo (>=16) when loading migration scripts: odoo.upgrade.<module>.<version>.<script>.

Повертає

модуль, створений з імпортованого скрипта оновлення

class once(lower, upper, logger=None)[source]

Run code only once in a version interval during a multi-step upgrade.

When the upgrade source and target are known (via the ODOO_UPG_DB_SOURCE_VERSION and ODOO_UPG_DB_TARGET_VERSION environment variables), this object evaluates to truthy only at the first upgrade step whose destination version falls within [lower, upper]. At every other step it evaluates to falsy.

When the environment variables are absent (e.g. in a single-step or standalone run), the object is truthy when the current version is in the interval [lower, upper]. A None value means unbound. At least one bound must be set.

It can be used as a plain boolean or as a decorator:

Example

As a boolean, run a migration only during the first step that reaches Odoo 17:

def migrate(cr, version):
    if util.once("17.0", "18.0"):
        util.rename_field(cr, "sale.order", "old_name", "new_name")

As a decorator, same effect, wrapping the whole function body:

@util.once("17.0", "18.0")
def migrate(cr, version):
    util.rename_field(cr, "sale.order", "old_name", "new_name")

Примітка

This is only meaningful in multi-step upgrades, i.e. for 0.0.0 scripts or symlinked scripts.

Параметри
  • lower (str or None) – lower bound of the version interval, inclusive. Defaults to the upgrade source version when None.

  • upper (str or None) – upper bound of the version interval, inclusive. Defaults to the upgrade target version when None.

  • logger (logging.Logger or None) – when set, a message is emitted on each evaluation reporting whether the wrapped code runs or is skipped at the current version.

parse_version(s)[source]

Перетворити рядок версії на ключ, який можна сортувати за хронологічним порядком

Це щось на зразок гібрида функцій StrictVersion і LooseVersion з бібліотеки distutils; якщо ви вкажете версії, які підходять для StrictVersion, то він поводитиметься так само; в іншому випадку він діятиме як дещо «розумніша» версія LooseVersion. Існує можливість створити патологічні схеми кодування версій, які зможуть ввести цей парсер в оману, але на практиці такі випадки мають бути дуже рідкісними.

Повернуте значення буде кортежем рядків. Числові частини версії доповнюються до 8 цифр, щоб їх можна було порівнювати як числа, але без урахування того, як числа порівнюються відносно рядків. Крапки опускаються, а тире зберігаються. Кінцеві нулі між літерними сегментами або тире приховуються, тому, наприклад, «2.4.0» вважається таким самим, як «2.4». Буквено-цифрові частини перетворюються на малі літери.

Алгоритм припускає, що такі символьні рядки, як «-», а також будь-який алфавітний рядок, що йде в алфавітному порядку після «final», позначають «рівень патча». Отже, «2.4-1» вважається гілкою або патчем «2.4», а тому «2.4.1» вважається новішим за «2.4-1», який, у свою чергу, є новішим за «2.4».

Строки на кшталт «a», «b», «c», «alpha», «beta», «candidate» тощо (які за алфавітом йдуть перед «final») вважаються попередніми версіями, тому версія «2.4» вважається новішою за «2.4a1».

Нарешті, для обробки різних випадків рядки «pre», «preview» та «rc» розглядаються так, ніби вони є «c», тобто ніби це кандидати на випуск, і тому вони не є настільки новими, як рядок версії, що не містить цих символів.

skippable_cm()[source]

Повернути менеджер контексту, щоб дозволити іншому менеджеру контексту не надавати дані.

Див. edit_view() для прикладу використання.

version_between(a, b)

Повертає, чи знаходиться поточна версія Odoo в діапазоні [a,b].

Див. також version_gte()

Примітка

Межі є інклюзивними.

Параметри
  • a (str) – Версія Odoo, нижня межа

  • b (str) – Версія Odoo, верхня межа

Тип повернення

bool

version_gte(version)

Повертає, чи поточна версія Odoo більша або дорівнює version.

Ця функція корисна для умовного виконання в скрипті оновлення, який застосовується до кількох версій, наприклад, скрипти 0.0.0.

Параметри

version (str) – Версія Odoo повинна відповідати формату [saas~]X.Y, де X - це основна версія Odoo, saas~ необхідний лише тоді, коли Y не дорівнює нулю

Тип повернення

bool

Звіт

Допоміжні функції для повідомлення про зміни, внесені під час оновлення.

Інформація, що генерується функціями звітності, після оновлення буде відображатися у вигляді публікацій у каналі Адміністратор.

Отримати HTML-посилання на запис у інтерфейсі Odoo.

Параметри
  • model (str) – назва технічної моделі.

  • id (int) – ID запису, на який потрібно встановити посилання.

  • name (str) – текст посилання (не обов’язково); якщо не вказано, за замовчуванням використовується «model(id=id)».

  • action_id (int) – додаткова дія, за допомогою якої можна відкрити запис.

Повертає

Тег HTML-посилання, обгорнутий у розмітку, якщо така є.

Тип повернення

str або markupsafe.Markup

html_escape()

Замініть символи &, <, >, ' та " у рядку на послідовності, безпечні для HTML. Використовуйте цю функцію, якщо вам потрібно відобразити в HTML текст, який може містити такі символи.

Якщо об’єкт має метод __html__, його викликають, і вважається, що значення, яке він повертає, вже є безпечним для HTML.

Параметри

s – Об’єкт, який потрібно перетворити на рядок та обробити для уникнення небажаних символів.

Повертає

Рядок типу Markup з текстом, що містить екрановані символи.

report_message(message, category='Other', format='text')[source]

Додати до звіту про оновлення новий запис, відформатований відповідно до format.

Параметри
  • message (str) – про що повідомляти.

  • category (str) – Заголовок запису звіту.

  • format (str) – формат, який використовується для відображення message. Підтримувані значення: - text: звичайний текст, з ескейп-символами, що відображається без змін. - html: відображається як необроблена HTML-розмітка. - md: відображається як Markdown і конвертується в HTML. - rst: відображається як reStructuredText і конвертується в HTML.

report_with_list(summary, data, columns, row_format, links=None, total=None, limit=100, category='Other')[source]

Додайте до звіту про оновлення новий запис, у якому відображається список записів.

Запис складається з категорії (заголовка) та короткого опису (основного тексту). У записі відображається список записів, раніше отриманих за допомогою SQL-запиту, або будь-який інший список.

Попередження

Якщо список, який потрібно відобразити, буде порожнім, у звіті нічого не відображатиметься.

Example

total = cr.rowcount
data = cr.fetchmany(20)
util.report_with_list(
    summary="The following records were altered.",
    data=data,
    columns=("id", "name", "city", "comment", "company_id", "company_name"),
    row_format="Partner with id {partner_link} works at company {company_link} in {city}, ({comment})",
    links={"company_link": ("res.company", "company_id", "company_name"), "partner_link": ("res.partner", "id", "name")},
    total=total,
    category="Accounting"
)
Параметри
  • summary (str) – опис запису у звіті.

  • data (list(tuple)) – дані для звіту; кожен запис становитиме один рядок у звіті.

  • columns (tuple(str)) – на стовпці в data можна посилатися в row_format

  • row_format (str) – формат для рядків; можна використовувати будь-яку назву з columns або links, наприклад: «Партнер {partner_link}, який мешкає в {city}, працює в компанії {company_link}».

  • links (dict(str, tuple(str, str, str))) – залежно від наявності специфікації посилань на моделі/записи, на ключі можна посилатися в row_format.

  • total (int) – необов’язковий параметр, загальна кількість записів. Якщо передано значення None, приймається як len(data). Корисно, коли data було обмежено викликом функції.

  • limit (int) – максимальна кількість записів, що відображаються у звіті. Якщо data містить більше записів, ніж limit, у звіт також буде включено значення total. Щоб скасувати обмеження, вкажіть None.

  • category (str) – заголовок запису у звіті.

report_with_summary(summary, details, category='Other')[source]

Додати новий запис до звіту про оновлення.

Параметри
  • summary (str) – Опис запису у звіті.

  • details (str) – Детальний опис, який за замовчуванням буде згорнутий.

  • category (str) – Заголовок запису звіту.

Testing upgrade scripts

Під час оновлення використовуються два основні класи для тестування.

  • UpgradeCase для тестування скриптів оновлення,

  • IntegrityCase for testing invariant values that must hold across versions.

Підкласи повинні реалізовувати:

  • For UpgradeCase:

    • prepare метод: підготовка даних перед оновленням,

    • check метод: перевірка правильності оновлення даних.

  • Для IntegrityCase:

    • invariant method: compute a value that must remain consistent before and after the upgrade.

Помістіть ваші тестові класи в модуль (папку) Python tests в будь-якій з папок, що містять скрипти оновлення ваших модулів. Скрипт, що містить ваші тести, повинен мати префікс test_. Модуль tests повинен містити файл __init__.py, щоб його було виявлено Odoo.

Приклад структури каталогів:

myupgrades/
└── mymodule1/
    ├── 18.0.1.1.2/
    │   └── pre-myupgrade.py
    └── tests/
        ├── __init__.py
        └── test_myupgrade.py

Примітка

Тести у наведеному вище прикладі будуть завантажені лише тоді, коли mymodule1 оновлюється

Running Upgrade Tests

Після отримання оновленої бази даних з усіма стандартними модулями Odoo, вже оновленими до цільової версії, ви можете протестувати оновлення користувацьких модулів, виконавши триетапний процес:

  1. Prepare the test data

    $ ~/odoo/$version/odoo-bin -d DB --test-tags=$prepare_test_tag \
      --upgrade-path=~/upgrade-util/src,~/myupgrades \
      --addons=~/odoo/$version/addons,~/enterprise/$version,~/mymodules --stop
    
  2. Оновити модулі

    $ ~/odoo/$version/odoo-bin -d DB -u mymodule1,mymodule2 \
      --upgrade-path=~/upgrade-util/src,~/myupgrades \
      --addons=~/odoo/$version/addons,~/enterprise/$version,~/mymodules --stop
    
  3. Перевірити оновлені дані

    $ ~/odoo/$version/odoo-bin -d DB --test-tags=$check_test_tag \
      --upgrade-path=~/upgrade-util/src,~/myupgrades \
      --addons=~/odoo/$version/addons,~/enterprise/$version,~/mymodules --stop
    

У наведеному вище прикладі припускається, що $version – це цільова версія вашого оновлення (наприклад, 18.0), DB – це назва вашої бази даних, а mymodule1,mymodule2 – це модулі, які ви хочете оновити. Структура каталогів припускає, що ~/odoo/$version та ~/enterprise/$version містять вихідний код Community та Enterprise для цільової версії Odoo відповідно. ~/mymodules містить код ваших користувацьких модулів (mymodule1, …), ~/myupgrades містить ваші користувацькі скрипти оновлення, а ~/upgrade-util містить репозиторій upgrade utils.

Змінні $prepare_test_tag та $check_test_tag необхідно встановити відповідно до:

Змінна

UpgradeCase

IntegrityCase

$prepare_test_tag

upgrade.test_prepare

integrity_case.test_prepare

$check_test_tag

upgrade.test_check

integrity_test.test_check

Примітка

upgrade.test_prepare також запускає тести IntegrityCase, тому ви можете підготувати дані як для тестів UpgradeCase, так і для IntegrityCase, використовуючи лише цей тег.

Попередження

Не запускайте жодного методу prepare класу UpgradeCase перед надсиланням бази даних на оновлення виробничого рівня на upgrade.odoo.com. Це може призвести до блокування оновлення та його позначки як невдалого.

Документація по API

class IntegrityCase(methodName='runTest')[source]

Test case for validating upgrade invariants.

Перевизначити:

  • invariant для повернення значення, що серіалізується за допомогою JSON, що представляє invariant для перевірки.

The invariant method is called both before and after the upgrade, and the results are compared. If there is any difference the test fails.

Example

from odoo.upgrade.testing import IntegrityCase


class NoNewUsers(IntegrityCase):
    def invariant(self):
        return self.env["res.users"].search_count([])
class UpgradeCase(methodName='runTest')[source]

Test case to verify the upgrade flow.

Перевизначити:

  • prepare до налаштування даних,

  • check для підтвердження очікувань після оновлення.

ORM можна використовувати в цих методах для виконання тестованого функціонального потоку. Повернене значення prepare зберігається та передається як аргумент check. Воно має бути JSON-серіалізованим.

Примітка

Оскільки prepare вводить або змінює дані, цей тип тесту призначений лише для розробки. Використовуйте його для тестування скриптів оновлення під час їх розробки. Не запускайте ці тести для оновлення в робочій версії. Щоб перевірити, чи зберегли оновлення важливі інваріанти у робочій версії, використовуйте замість цього тести IntegrityCase.

Example

from odoo.upgrade.testing import UpgradeCase, change_version


class DeactivateBobUsers(UpgradeCase):

    def prepare(self):
        u = self.env["res.users"].create({"login": "bob", "name": "Bob"})
        return u.id  # will be passed to check

    def check(self, uid):  # uid is the value returned by prepare
        self.env.cr.execute(
            "SELECT * FROM res_users WHERE id=%s AND NOT active", [uid]
        )
        self.assertEqual(self.env.cr.rowcount, 1)
change_version(version_str)[source]

Декоратор класу для визначення версії, для якої релевантний тест.

Використання @change_version(version) означає:

  • test_prepare запуститься лише тоді, коли поточна версія Odoo знаходиться в діапазоні [next_major_version-1, version).

  • test_check буде виконуватися лише тоді, коли поточна версія Odoo знаходиться в діапазоні [version, next_major_version).

next_major_version - це наступна основна версія після version, наприклад, для saas~17.2 це 18.0.

Примітка

Не використовуйте цей декоратор, якщо ваше оновлення знаходиться в тій самій основній версії. В іншому випадку ваші тести не будуть виконані.

parametrize(argvalues)[source]

Параметризуйте тестову функцію.

Decorator for upgrade test functions to parametrize and generate multiple tests from it. The new test functions are injected in the containing class. Inspired by the parameterized package.

Example

@parametrize([(1, 2), (2, 4), (-1, -2), (0, 0)])
def test_double(self, input, expected):
    self.assertEqual(input * 2, expected)

This will generate four test methods: test_double__0, test_double__1, test_double__2, and test_double__3, each with different argument values.

Параметри

argvalues (list(tuple)) – Arguments for each test case. Each tuple will be unpacked and passed as arguments to the test function.