-
-
Notifications
You must be signed in to change notification settings - Fork 821
[ADD] Migration scripts for the project addon #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| <?xml version='1.0' encoding='utf-8'?> | ||
| <openerp> | ||
| <data> | ||
| <record id="project_tt_merge" model="project.task.type"><field name="state"/><field name="sequence">14</field> | ||
| </record> | ||
| <record id="project_tt_cancel" model="project.task.type"><field name="state"/><field name="sequence">30</field> | ||
| </record> | ||
| <record id="task_visibility_rule" model="ir.rule"><field name="domain_force">['|', | ||
| ('project_id.privacy_visibility', 'in', ['public', 'employees']), | ||
| '&', | ||
| ('project_id.privacy_visibility', '=', 'followers'), | ||
| ('message_follower_ids', 'in', [user.partner_id.id]), | ||
| ]</field> | ||
| <field name="name">Project/Task: employees: public or employee or (followers and following)</field> | ||
| </record> | ||
| <record id="project_tt_specification" model="project.task.type"><field name="state"/><field name="sequence">10</field> | ||
| </record> | ||
| <record id="project_tt_analysis" model="project.task.type"><field name="case_default" eval="True"/> | ||
| <field name="state"/></record> | ||
| <record id="all_projects_account" model="account.analytic.account"><field name="code">PP001</field> | ||
| </record> | ||
| <record id="project_tt_testing" model="project.task.type"><field name="state"/><field name="sequence">13</field> | ||
| </record> | ||
| <record id="project_tt_design" model="project.task.type"><field name="state"/><field name="sequence">11</field> | ||
| </record> | ||
| <record id="project_tt_development" model="project.task.type"><field name="state"/><field name="sequence">12</field> | ||
| </record> | ||
| <record id="project_tt_deployment" model="project.task.type"><field name="state"/><field name="sequence">20</field> | ||
| </record> | ||
| </data> | ||
| </openerp> | ||
|
|
76 changes: 76 additions & 0 deletions
76
addons/project/migrations/8.0.1.1/openupgrade_analysis_work.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| ---Fields in module 'project'--- | ||
| # NTD cosmetic change | ||
| project / project.project / doc_count (int) : type is now 'integer' ('int') | ||
|
|
||
| # Apply set_message_last_post | ||
| project / project.project / message_last_post (datetime) : NEW | ||
| project / project.task / message_last_post (datetime) : NEW | ||
|
|
||
| # NTD Reverse relation of existing many2one on task model | ||
| project / project.project / task_ids (one2many) : NEW relation: project.task | ||
| # NTD Tracking a write on the task stage_id. No meaningful value to apply during migration. | ||
| project / project.task / date_last_stage_update (datetime): NEW | ||
|
|
||
| # Adapt to new semantics and range | ||
| project / project.task / priority (selection) : selection_keys is now '['0', '1', '2']' ('['0', '1', '2', '3', '4']') | ||
|
|
||
| # NTD Existing table column now referred in the model | ||
| project / project.task / write_date (datetime) : NEW | ||
|
|
||
| # NTD State is no longer available on task, therefore neither in the history. | ||
| 2project / project.task.history / state (selection) : DEL selection_keys: ['cancelled', 'done', 'draft', 'open', 'pending'] | ||
| project / project.task.history.cumulative / state (selection) : DEL selection_keys: ['cancelled', 'done', 'draft', 'open', 'pending'] | ||
| project / project.task.type / state (selection) : DEL required: required, selection_keys: ['cancelled', 'done', 'draft', 'open', 'pending'], req_default: open | ||
|
|
||
| # NTD this report is a view, not table | ||
| project / report.project.task.user / date_last_stage_update (date) : NEW | ||
| project / report.project.task.user / day (char) : DEL | ||
| project / report.project.task.user / month (selection) : DEL selection_keys: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'] | ||
| project / report.project.task.user / priority (selection) : selection_keys is now '['0', '1', '2']' ('['0', '1', '2', '3', '4']') | ||
| project / report.project.task.user / stage_id (many2one) : NEW relation: project.task.type | ||
| project / report.project.task.user / year (char) : DEL | ||
|
|
||
| # Additionally, take into account how project aliases are now configured | ||
| # in the project's create() method. Adapt existing aliases. | ||
|
|
||
| ---XML records in module 'project'--- | ||
| # Regular updated data | ||
| DEL ir.actions.act_window: project.action_project_task_reevaluate | ||
| DEL ir.actions.act_window: project.my_open_tasks_action | ||
| DEL ir.actions.act_window: project.open_board_project | ||
| NEW ir.model.access: project.access_mail_alias | ||
| NEW ir.model.access: project.access_project_task_type_manager | ||
| NEW ir.model.access: project.access_resource_calendar_leaves_user | ||
| DEL ir.ui.menu: project.menu_project_dashboard | ||
| NEW ir.ui.view: project.assets_backend | ||
| DEL ir.ui.view: project.board_project_form | ||
| DEL ir.ui.view: project.view_project_task_reevaluate | ||
| DEL ir.ui.view: project.view_task_history_tree | ||
| DEL ir.ui.view: project.view_task_project_user_tree | ||
| DEL ir.ui.view: project.view_task_tree | ||
|
|
||
| # Rename functionally similar mail subtype ids | ||
| DEL mail.message.subtype: project.mt_project_task_started | ||
| NEW mail.message.subtype: project.mt_project_task_assigned | ||
| DEL mail.message.subtype: project.mt_task_closed | ||
| NEW mail.message.subtype: project.mt_task_assigned | ||
| DEL mail.message.subtype: project.mt_task_started | ||
| NEW mail.message.subtype: project.mt_task_ready | ||
|
|
||
| # No more mail subtype for a project's task end of life | ||
| DEL mail.message.subtype: project.mt_project_task_closed | ||
|
|
||
| # Data for abandoned process module | ||
| DEL process.node: project.process_node_donetask0 | ||
| DEL process.node: project.process_node_drafttask0 | ||
| DEL process.node: project.process_node_opentask0 | ||
| DEL process.node: project.process_node_taskbydelegate0 | ||
| DEL process.process: project.process_process_tasksprocess0 | ||
| DEL process.transition: project.process_transition_delegate0 | ||
| DEL process.transition: project.process_transition_draftopentask0 | ||
| DEL process.transition: project.process_transition_opendonetask0 | ||
| DEL process.transition.action: project.process_transition_action_draftcanceltask0 | ||
| DEL process.transition.action: project.process_transition_action_draftopentask0 | ||
| DEL process.transition.action: project.process_transition_action_opencanceltask0 | ||
| DEL process.transition.action: project.process_transition_action_opendrafttask0 | ||
| DEL process.transition.action: project.process_transition_action_openpendingtask0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # -*- coding: utf-8 -*- | ||
| ############################################################################## | ||
| # | ||
| # Odoo, a suite of business apps | ||
| # This module Copyright (C) 2014 Therp BV (<http://therp.nl>). | ||
| # | ||
| # This program is free software: you can redistribute it and/or modify | ||
| # it under the terms of the GNU Affero General Public License as | ||
| # published by the Free Software Foundation, either version 3 of the | ||
| # License, or (at your option) any later version. | ||
| # | ||
| # This program is distributed in the hope that it will be useful, | ||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| # GNU Affero General Public License for more details. | ||
| # | ||
| # You should have received a copy of the GNU Affero General Public License | ||
| # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| ############################################################################## | ||
|
|
||
| from openerp.modules.registry import RegistryManager | ||
| from openerp import SUPERUSER_ID as uid | ||
| from openerp.openupgrade import openupgrade, openupgrade_80 | ||
|
|
||
|
|
||
| @openupgrade.migrate() | ||
| def migrate(cr, version): | ||
| registry = RegistryManager.get(cr.dbname) | ||
|
|
||
| openupgrade.map_values( | ||
| cr, | ||
| openupgrade.get_legacy_name('priority'), | ||
| 'priority', | ||
| [('4', '0'), ('3', '0'), ('2', '1'), ('1', '2'), ('0', '2')], | ||
| table='project_task', write='sql') | ||
|
|
||
| openupgrade_80.update_aliases( | ||
| cr, registry, 'project.project', | ||
| set_parent_thread_id=True, | ||
| defaults_id_key='project_id') | ||
|
|
||
| openupgrade_80.set_message_last_post( | ||
| cr, uid, registry, ['project.project', 'project.task'] | ||
| ) | ||
|
|
||
| openupgrade.load_data( | ||
| cr, 'project', 'migrations/8.0.1.1/noupdate_changes.xml') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # -*- coding: utf-8 -*- | ||
| ############################################################################## | ||
| # | ||
| # Odoo, a suite of business apps | ||
| # This module Copyright (C) 2014 Therp BV (<http://therp.nl>). | ||
| # | ||
| # This program is free software: you can redistribute it and/or modify | ||
| # it under the terms of the GNU Affero General Public License as | ||
| # published by the Free Software Foundation, either version 3 of the | ||
| # License, or (at your option) any later version. | ||
| # | ||
| # This program is distributed in the hope that it will be useful, | ||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| # GNU Affero General Public License for more details. | ||
| # | ||
| # You should have received a copy of the GNU Affero General Public License | ||
| # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| ############################################################################## | ||
|
|
||
| from openerp.openupgrade import openupgrade | ||
|
|
||
|
|
||
| column_renames = { | ||
| 'project_task': [('priority', None)]} | ||
|
|
||
| xmlid_renames = [ | ||
| ('project.mt_project_task_started', 'project.mt_project_task_assigned'), | ||
| ('project.mt_task_started', 'project.mt_task_assigned'), | ||
| ('project.mt_task_closed', 'project.mt_task_ready'), | ||
| ] | ||
|
|
||
|
|
||
| @openupgrade.migrate() | ||
| def migrate(cr, version): | ||
| openupgrade.rename_columns(cr, column_renames) | ||
| openupgrade.rename_xmlids(cr, xmlid_renames) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,6 +58,7 @@ | |
| 'check_values_selection_field', | ||
| 'move_field_m2o', | ||
| 'convert_field_to_html', | ||
| 'map_values', | ||
| ] | ||
|
|
||
|
|
||
|
|
@@ -67,6 +68,8 @@ def check_values_selection_field(cr, table_name, field_name, allowed_values): | |
| has only the values 'allowed_values'. | ||
| If not return False and log an error. | ||
| If yes, return True. | ||
|
|
||
| .. versionadded:: 8.0 | ||
| """ | ||
| res = True | ||
| cr.execute("SELECT %s, count(*) FROM %s GROUP BY %s;" % | ||
|
|
@@ -197,6 +200,8 @@ def rename_xmlids(cr, xmlids_spec): | |
| One usage example is when an ID changes module. In OpenERP 6 for example, | ||
| a number of res_groups IDs moved to module base from other modules ( | ||
| although they were still being defined in their respective module). | ||
|
|
||
| :param xmlids_spec: a list of tuples (old module.xmlid, new module.xmlid). | ||
| """ | ||
| for (old, new) in xmlids_spec: | ||
| if not old.split('.') or not new.split('.'): | ||
|
|
@@ -401,12 +406,17 @@ def write_value(ids, field, value): | |
|
|
||
| def logged_query(cr, query, args=None): | ||
| """ | ||
| Logs query and affected rows at level DEBUG | ||
| Logs query and affected rows at level DEBUG. | ||
|
|
||
| :param query: a query string suitable to pass to cursor.execute() | ||
| :param args: a list, tuple or dictionary passed as substitution values \ | ||
| to cursor.execute(). | ||
| """ | ||
| if args is None: | ||
| args = [] | ||
| args = () | ||
| args = tuple(args) if type(args) == list else args | ||
| cr.execute(query, args) | ||
| logger.debug('Running %s', query % tuple(args)) | ||
| logger.debug('Running %s', query % args) | ||
| logger.debug('%s rows affected', cr.rowcount) | ||
| return cr.rowcount | ||
|
|
||
|
|
@@ -520,6 +530,65 @@ def float_to_integer(cr, table, field): | |
| }) | ||
|
|
||
|
|
||
| def map_values( | ||
| cr, source_column, target_column, mapping, | ||
| model=None, table=None, write='sql'): | ||
| """ | ||
| Map old values to new values within the same model or table. Old values | ||
| presumably come from a legacy column. | ||
|
|
||
| :param cr: The database cursor | ||
| :param source_column: the database column that contains old values to be \ | ||
| mapped | ||
| :param target_column: the database column, or model field (if 'write' is \ | ||
| 'orm') that the new values are written to | ||
| :para mapping: list of tuples [(old value, new value)] | ||
| :param model: used for writing if 'write' is 'orm', or to retrieve the \ | ||
| table if 'table' is not given. | ||
| :param table: the database table used to query the old values, and write \ | ||
| the new values (if 'write' is 'sql') | ||
| :param write: Either 'orm' or 'sql'. Note that old ids are always \ | ||
| identified by an sql read. | ||
|
|
||
| .. versionadded:: 8.0 | ||
| """ | ||
|
|
||
| if write not in ('sql', 'orm'): | ||
| logger.exception( | ||
| "map_values is called with unknown value for write param: %s", | ||
| write) | ||
| if not table: | ||
| if not model: | ||
| logger.exception("map_values is called with no table and no model") | ||
| table = model._table | ||
| if source_column == target_column: | ||
| logger.exception( | ||
| "map_values is called with the same value for source and old" | ||
| " columns : %s", | ||
| source_column) | ||
| for old, new in mapping: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a check for avoiding using the same column as source and target. |
||
| values = { | ||
| 'table': table, | ||
| 'source': source_column, | ||
| 'target': target_column, | ||
| 'old': old, | ||
| 'new': new, | ||
| } | ||
| if write == 'sql': | ||
| query = """UPDATE %(table)s | ||
| SET %(target)s = %%(new)s | ||
| WHERE %(source)s = %%(old)s""" % values | ||
| else: | ||
| query = """SELECT id FROM %(table)s | ||
| WHERE %(source)s = %%(old)s""" % values | ||
| logged_query(cr, query, values) | ||
| if write == 'orm': | ||
| model.write( | ||
| cr, SUPERUSER_ID, | ||
| [row[0] for row in cr.fetchall()], | ||
| {target_column: new}) | ||
|
|
||
|
|
||
| def message(cr, module, table, column, | ||
| message, *args, **kwargs): | ||
| """ | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will cause a regression on a bug when args was passed as a list.
cr.execute was ok with lists IIRC
EDIT, just look at L373:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is not very pretty but it is trivial of course:
On my initial review I checked that all occurrences I could find in openupgrade-addons/7.0 pass a tuple, not a list. Do you have a concrete example where a list is passed that would trigger a regression? In fact, does that not break cr.execute which I believe does not take a list of arguments very well instead of a tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember running into this bug in 7.0 migration, I was calling logged query with a list.
I am resposible for the tuple being there in the first place.
If we support args as a dict, why not proof it for lists as well.
I don't want this back and forth of
argsandtuple(args)to go on forever ;)And the concrete example is right there, two lines above:
It seems really senseless to proof it with
Noneto thecr.executeand then have it fail on the next line.These four lines should be compatible with eachother.
Edit: I realise that
[]is an edge case which will not cause a fail, but I think my point still stands. If I look at the code, it tells me thatargsis expected to be a list. I will therefore use aargsas a list and run into this bug.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now see that you actually can pass a list to cursor.execute(), so we should settle for
args = tuple(args) if typeof(args) == list else argsthen-- EDIT-- Done.