# -*- coding: utf-8 -*- ########################################################################### # Copyright (c), The AiiDA team. All rights reserved. # # This file is part of the AiiDA code. # # # # The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # # For further information on the license, see the LICENSE.txt file # # For further information please visit http://www.aiida.net # ########################################################################### # pylint: disable=invalid-name,no-member """Data migration for legacy `JobCalculations`. These old nodes have already been migrated to the correct `CalcJobNode` type in a previous migration, but they can still contain a `state` attribute with a deprecated `JobCalcState` value and they are missing a value for the `process_state`, `process_status`, `process_label` and `exit_status`. The `process_label` is impossible to infer consistently in SQL so it will be omitted. The other will be mapped from the `state` attribute as follows: .. code-block:: text Old state | Process state | Exit status | Process status ---------------------|----------------|-------------|---------------------------------------------------------- `NEW` | `Killed` | `None` | Legacy `JobCalculation` with state `NEW` `TOSUBMIT` | `Killed` | `None` | Legacy `JobCalculation` with state `TOSUBMIT` `SUBMITTING` | `Killed` | `None` | Legacy `JobCalculation` with state `SUBMITTING` `WITHSCHEDULER` | `Killed` | `None` | Legacy `JobCalculation` with state `WITHSCHEDULER` `COMPUTED` | `Killed` | `None` | Legacy `JobCalculation` with state `COMPUTED` `RETRIEVING` | `Killed` | `None` | Legacy `JobCalculation` with state `RETRIEVING` `PARSING` | `Killed` | `None` | Legacy `JobCalculation` with state `PARSING` `SUBMISSIONFAILED` | `Excepted` | `None` | Legacy `JobCalculation` with state `SUBMISSIONFAILED` `RETRIEVALFAILED` | `Excepted` | `None` | Legacy `JobCalculation` with state `RETRIEVALFAILED` `PARSINGFAILED` | `Excepted` | `None` | Legacy `JobCalculation` with state `PARSINGFAILED` `FAILED` | `Finished` | 2 | - `FINISHED` | `Finished` | 0 | - `IMPORTED` | - | - | - Note the `IMPORTED` state was never actually stored in the `state` attribute, so we do not have to consider it. The old `state` attribute has to be removed after the data is migrated, because its value is no longer valid or useful. Note: in addition to the three attributes mentioned in the table, all matched nodes will get `Legacy JobCalculation` as their `process_label` which is one of the default columns of `verdi process list`. Revision ID: 26d561acd560 Revises: 07fac78e6209 Create Date: 2019-06-22 09:55:25.284168 """ # pylint: disable=invalid-name,no-member,import-error,no-name-in-module,line-too-long from alembic import op from sqlalchemy.sql import text # revision identifiers, used by Alembic. revision = '26d561acd560' down_revision = '07fac78e6209' branch_labels = None depends_on = None [docs]def upgrade(): """Migrations for the upgrade.""" conn = op.get_bind() # pylint: disable=no-member # Note that the condition on matching target nodes is done only on the `node_type` amd the `state` attribute value. # New `CalcJobs` will have the same node type and while their active can have a `state` attribute with a value # of the enum `CalcJobState`, some of which match the deprecated `JobCalcState`, however, the new ones are stored # in lower case, so we do not run the risk of matching them by accident. statement = text( """ UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "killed", "process_status": "Legacy `JobCalculation` with state `NEW`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "NEW"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "killed", "process_status": "Legacy `JobCalculation` with state `TOSUBMIT`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "TOSUBMIT"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "killed", "process_status": "Legacy `JobCalculation` with state `SUBMITTING`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "SUBMITTING"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "killed", "process_status": "Legacy `JobCalculation` with state `WITHSCHEDULER`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "WITHSCHEDULER"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "killed", "process_status": "Legacy `JobCalculation` with state `COMPUTED`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "COMPUTED"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "killed", "process_status": "Legacy `JobCalculation` with state `RETRIEVING`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "RETRIEVING"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "killed", "process_status": "Legacy `JobCalculation` with state `PARSING`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "PARSING"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "excepted", "process_status": "Legacy `JobCalculation` with state `SUBMISSIONFAILED`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "SUBMISSIONFAILED"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "excepted", "process_status": "Legacy `JobCalculation` with state `RETRIEVALFAILED`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "RETRIEVALFAILED"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "excepted", "process_status": "Legacy `JobCalculation` with state `PARSINGFAILED`", "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "PARSINGFAILED"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "finished", "exit_status": 2, "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "FAILED"}'; UPDATE db_dbnode SET attributes = attributes - 'state' || '{"process_state": "finished", "exit_status": 0, "process_label": "Legacy JobCalculation"}' WHERE node_type = 'process.calculation.calcjob.CalcJobNode.' AND attributes @> '{"state": "FINISHED"}'; """ ) conn.execute(statement) [docs]def downgrade(): """Migrations for the downgrade."""