def to_python(self, value): """Return a ProjectSignature value from the field contents. Args: value (object): The current value assigned to the field. This might be serialized string content or a :py:class:`~django_evolution.signatures.ProjectSignature` instance. Returns: django_evolution.signatures.ProjectSignature: The project signature stored in the field. Raises: django.core.exceptions.ValidationError: The field contents are of an unexpected type. """ if isinstance(value, six.string_types): if value.startswith('json!'): loaded_value = json.loads(value[len('json!'):], object_pairs_hook=OrderedDict) else: loaded_value = pickle_loads(value) return ProjectSignature.deserialize(loaded_value) elif isinstance(value, ProjectSignature): return value else: raise ValidationError( 'Unsupported serialized signature type %s' % type(value), code='invalid', params={ 'value': value, })
def to_python(self, value): """Return a ProjectSignature value from the field contents. Args: value (object): The current value assigned to the field. This might be serialized string content or a :py:class:`~django_evolution.signatures.ProjectSignature` instance. Returns: django_evolution.signatures.ProjectSignature: The project signature stored in the field. Raises: django.core.exceptions.ValidationError: The field contents are of an unexpected type. """ if isinstance(value, six.string_types): return ProjectSignature.deserialize(pickle_loads(value)) elif isinstance(value, ProjectSignature): return value else: raise ValidationError('Unsupported serialized signature type %s' % type(value), code='invalid', params={ 'value': value, })
def simulate(self, simulation): """Simulate a mutation for an application. This will run the :py:attr:`update_func` provided when instantiating the mutation, passing it ``app_label`` and ``project_sig``. It should then modify the signature to match what the SQL statement would do. Args: simulation (Simulation): The state for the simulation. Raises: django_evolution.errors.CannotSimulate: :py:attr:`update_func` was not provided or was not a function. django_evolution.errors.SimulationFailure: The simulation failed. The reason is in the exception's message. This would be run by :py:attr:`update_func`. """ if callable(self.update_func): if hasattr(inspect, 'getfullargspec'): # Python 3 argspec = inspect.getfullargspec(self.update_func) else: # Python 2 argspec = inspect.getargspec(self.update_func) if len(argspec.args) == 1 and argspec.args[0] == 'simulation': # New-style simulation function. self.update_func(simulation) return elif len(argspec.args) == 2: # Legacy simulation function. project_sig = simulation.project_sig serialized_sig = project_sig.serialize(sig_version=1) self.update_func(simulation.app_label, serialized_sig) new_project_sig = ProjectSignature.deserialize(serialized_sig) # We have to reconstruct the existing project signature's state # based on this. app_sig_ids = [ app_sig.app_id for app_sig in new_project_sig.app_sigs ] for app_sig_id in app_sig_ids: project_sig.remove_app_sig(app_sig_id) for app_sig in new_project_sig.app_sigs: project_sig.add_app_sig(app_sig) return raise CannotSimulate( 'SQLMutations must provide an update_func(simulation) or ' 'legacy update_func(app_label, project_sig) parameter ' 'in order to be simulated.')