Утиліти оновлення¶
Утиліти оновлення - це бібліотека, що містить допоміжні функції для полегшення написання скриптів оновлення. Ця бібліотека, яка використовується 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 встановити модуль.
- force_upgrade_of_fresh_module(cr, module, init=True)[source]¶
Примусово запустити виконання скриптів оновлення для модуля, що встановлюється.
Стандартна версія Odoo не запускає скрипти оновлення під час інсталяції модуля. Це логічно, оскільки, з технічної точки зору, модуль не оновлюється. Проте трапляються випадки, коли (новий) модуль повинен виконати певні операції для правильної інсталяції, наприклад, отримати дані з іншого модуля. Це часто трапляється, коли модуль функціонально розділений на кілька модулів.
- Параметри
Перебування в режимі ініціалізації має побічний ефект неврахування прапорців 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) – чи оновлюються залежності модулів, що залежать від
oldxmlid_mapping (dict) – необов’язкове відображення
{old_name: new_name}для перейменування XMLID у процесі об’єднання. Використовуйте це, якщо XMLID зoldінакше конфліктував би за назвою з тим, що вже є вinto. Див.rename_xmlid()
- module_installed(cr, module)[source]¶
Повертає інформацію про те, чи встановлено модуль.
Див.
modules_installed().
- modules_installed(cr, *modules)[source]¶
Повертає, чи встановлено всі задані модулі.
Примітка
У контексті оновлень модуль вважається встановленим, якщо він позначений для оновлення або встановлення; навіть якщо вони ще не повністю встановлені.
- 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().
- uninstall_module(cr, module)[source]¶
Деінсталювати та видалити всі записи, що належать модулю.
- Параметри
module (str) – назва модуля для видалення
- uninstall_theme(cr, theme, base_theme=None)[source]¶
Деінсталюйте модуль теми та видаліть його з вебсайтів.
- Параметри
Попередження
Цю функцію можна використовувати лише в
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]¶
Видалити модель та її посилання з бази даних.
Деякі обов’язкові непрямі посилання на модель замінюються на невідому модель - порожню модель, яка слугує заповнювачем для зниклих моделей.
- 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_messageon the record’s chatter.If the
mailmodule is not installed (nomail_messagetable), the value is dumped intofallback_columnwhen 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
formatstring with a single%sis allowed. If%sis missing,: %sis 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_idtarget.fk_display (str or None) – when
columnis 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
mailmodule is not installed (nomail_messagetable). The column must exist (e.g.res_partner.comment), raises otherwise. Translated (jsonb) columns are written through theiren_USkey.where (str) – extra SQL
WHEREcondition on the source records. It is astr.formattemplate 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 notNULL(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]¶
Перейменувати логічне поле та інвертувати його значення.
- 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) – чи видаляються стовпці поля в режимі
CASCADEdrop_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) – чи деактивувати записи, які неможливо видалити, оскільки на них є посилання, за замовчуванням
Falsekeep_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.
- Повертає
список ідентифікаторів видалених записів, якщо такі є
- Тип повернення
- 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_idactive (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.- Параметри
- Повертає
ідентифікатор запису, що відповідає значенню,
None, якщо запис не знайдено- Тип повернення
Порада
Ця функція корисна під час міграції записів з бази даних у користувацький модуль, щоб створити xml_ids перед оновленням модуля та уникнути дублювання.
- 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.
- refs(cr, xmlids, strict=False)[source]¶
Return a mapping of xmlid -> res_id for the given list of xmlids.
- Параметри
- Повертає
dict mapping each xmlid to its res_id; missing xmlids map to
Noneunlessstrict=True, in which case they are omitted from the result.- Тип повернення
- 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, що посилається на перегляд з IDview_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; перегляд, що належить до модуля, видаляється, а визначений користувачем - вимикається.
- 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.namenew (str) – новий xml_id запису у форматі
module.namenoupdate (bool or None) – значення, яке потрібно встановити для прапорця
noupdatexml_id, ігнорується, якщоNoneon_collision (str) – як діяти далі, якщо xml_id вже існує, варіанти:
mergeабоfail(за замовчуванням)
- Повертає
ID запису, на який посилається новий xml_id,
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, обгорнутим
PGRegexpnew (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.namereset_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може знадобитися щоразу, коли дані змінюються безпосередньо в базі даних.- Повертає
нове середовище
- Тип повернення
- get_inherit_model_names(model)[source]¶
Get the names of the models the model directly or indirectly
_inherit.
- 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 whenidshas 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) – кількість записів для завантаження в кожному фрагменті ітерації, за замовчуванням
200yield_chunks (bool) – when iterating, yield records in chunks of
chunk_sizeinstead of one by one. Default isFalselogger (
logging.Logger) – логер, який використовується для звітування про прогрес, за замовчуванням_loggerstrategy (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
idshas no__length__or with queryquery (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: використовувати метод
flushORMcommit:
commitкурсор - також скинутиauto: вибрати найкращий варіант між двома вищезазначеними, враховуючи кількість записів для обчислення та наявність відстежуваних полів.
Стратегія commit менш схильна до виникнення помилки
MemoryErrorдля величезного обсягу даних.- Параметри
model (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викликається лише на листках, які використовують полеoldmodelяк остання частину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) – назва поля, яке має замінити
oldadapter (function) – адаптер для відпусток
skip_inherit (list(str)) – список успадкованих назв моделей, які не потрібно адаптувати (пропустити)
force_adapt (bool) – якщо
True, запускатиadapterна всіх листках, що маютьnewу лівій частині листка (шляху), корисно під час видалення поля (у цьому випадкуnewігнорується).
SQL¶
Функції утилыти для взаємодії з PostgreSQL.
- class ColumnList(list_=(), quoted=())[source]¶
Інкапсулюйте список елементів, що представляють назви стовпців.
Результуючий об’єкт можна відобразити як рядок з початковою/кінцевою комою або аліасом.
- Параметри
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 зі списку назв колонок, які можуть потребувати лапок.
- class PGRegexp[source]¶
Обгортка для семантичного значення параметрів: цей рядок є регулярним виразом Postgres.
- 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-даних через мапінг.
- 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.
- 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
AUTOto infer the type from theidcolumn offk_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, дійсне лише якщо колонка є зовнішнім ключем.
- Повертає
чи було створено колонку
- Тип повернення
- 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"
- Повертає
назва щойно створеної/виправленої таблиці
- Тип повернення
- 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для кожного виконання запиту- Тип повернення
Попередження
Користувач, який здійснює виклик, повинен переконатися, що запити не оновлюють одні й ті ж записи в різних сегментах. Не рекомендується використовувати цю функцію для запитів
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]¶
Повернути список колонок у таблиці.
- Параметри
- Повертає
список назв колонок, присутніх у таблиці
- Тип повернення
- get_common_columns(cr, table1, table2, ignore=('id',), type_check=True)[source]¶
Повернути список колонок, присутніх в обох таблицях.
- Параметри
- Повертає
список імен стовпців, що містяться в обох таблицях
- Тип повернення
- 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
dictfetchmanyanddictfetchall. 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().- Параметри
- Повертає
сума
cr.rowcountдля кожного виконання запиту- Тип повернення
Попередження
Через особливості функції
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.- Параметри
- Повертає
чи було знято обмеження
- Тип повернення
Різне¶
Різні автономні функції.
- 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.pydef my_util(cr): # do stuff
У
myothermodule/16.0.1.0/post-migrate.pyfrom 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 frompathto 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_VERSIONandODOO_UPG_DB_TARGET_VERSIONenvironment 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]. ANonevalue 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.0scripts 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()Примітка
Межі є інклюзивними.
- version_gte(version)¶
Повертає, чи поточна версія Odoo більша або дорівнює
version.Ця функція корисна для умовного виконання в скрипті оновлення, який застосовується до кількох версій, наприклад, скрипти
0.0.0.
Звіт¶
Допоміжні функції для повідомлення про зміни, внесені під час оновлення.
Інформація, що генерується функціями звітності, після оновлення буде відображатися у вигляді публікацій у каналі Адміністратор.
- get_anchor_link_to_record(model, id, name=None, action_id=None)[source]¶
Отримати HTML-посилання на запис у інтерфейсі Odoo.
- Параметри
- Повертає
Тег 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_formatrow_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) – заголовок запису у звіті.
Testing upgrade scripts¶
Під час оновлення використовуються два основні класи для тестування.
UpgradeCaseдля тестування скриптів оновлення,IntegrityCasefor testing invariant values that must hold across versions.
Підкласи повинні реалізовувати:
For
UpgradeCase:prepareметод: підготовка даних перед оновленням,checkметод: перевірка правильності оновлення даних.
Для
IntegrityCase:invariantmethod: 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, вже оновленими до цільової версії, ви можете протестувати оновлення користувацьких модулів, виконавши триетапний процес:
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
Оновити модулі
$ ~/odoo/$version/odoo-bin -d DB -u mymodule1,mymodule2 \ --upgrade-path=~/upgrade-util/src,~/myupgrades \ --addons=~/odoo/$version/addons,~/enterprise/$version,~/mymodules --stop
Перевірити оновлені дані
$ ~/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 необхідно встановити відповідно до:
Змінна |
|
|
|---|---|---|
|
|
|
|
|
|
Примітка
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
invariantmethod 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, andtest_double__3, each with different argument values.