示例#1
0
文件: evolve.py 项目: CARocha/sequia
def get_mutations(app, evolution_labels):
    """
    Obtain the list of mutations described by the named evolutions.
    """
    # For each item in the evolution sequence. Check each item to see if it is
    # a python file or an sql file.
    try:
        app_name = '.'.join(app.__name__.split('.')[:-1])
        evolution_module = __import__(app_name + '.evolutions', {}, {}, [''])
    except ImportError:
        return []

    mutations = []
    for label in evolution_labels:
        directory_name = os.path.dirname(evolution_module.__file__)
        sql_file_name = os.path.join(directory_name, label + '.sql')
        if os.path.exists(sql_file_name):
            sql = []
            sql_file = open(sql_file_name)
            for line in sql_file:
                sql.append(line)
            mutations.append(SQLMutation(label, sql))
        else:
            try:
                module_name = [evolution_module.__name__, label]
                module = __import__('.'.join(module_name), {}, {},
                                    [module_name])
                mutations.extend(module.MUTATIONS)
            except ImportError, e:
                raise EvolutionException(
                    'Error: Failed to find an SQL or Python evolution named %s'
                    % label)
示例#2
0
def get_mutations(app, evolution_labels, database):
    """
    Obtain the list of mutations described by the named evolutions.
    """
    # For each item in the evolution sequence. Check each item to see if it is
    # a python file or an sql file.
    try:
        app_name = '.'.join(app.__name__.split('.')[:-1])

        if app_name in BUILTIN_SEQUENCES:
            module_name = 'django_evolution.builtin_evolutions'
        else:
            module_name = '%s.evolutions' % app_name

        evolution_module = __import__(module_name, {}, {}, [''])
    except ImportError:
        return []

    mutations = []

    for label in evolution_labels:
        directory_name = os.path.dirname(evolution_module.__file__)

        # The first element is used for compatibility purposes.
        filenames = [
            os.path.join(directory_name, label + '.sql'),
            os.path.join(directory_name, "%s_%s.sql" % (database, label)),
        ]

        found = False

        for filename in filenames:
            if os.path.exists(filename):
                sql = []
                sql_file = open(sql_file_name)

                for line in sql_file:
                    sql.append(line)

                mutations.append(SQLMutation(label, sql))

                found = True
                break

        if not found:
            try:
                module_name = [evolution_module.__name__, label]
                module = __import__('.'.join(module_name),
                                    {}, {}, [module_name]);
                mutations.extend(module.MUTATIONS)
            except ImportError:
                raise EvolutionException(
                    'Error: Failed to find an SQL or Python evolution named %s'
                    % label)

    return mutations
示例#3
0
文件: evolve.py 项目: shash/IconDB
def get_mutations(app, evolution_labels, database):
    """
    Obtain the list of mutations described by the named evolutions.
    """
    # For each item in the evolution sequence. Check each item to see if it is
    # a python file or an sql file.
    try:
        app_name = '.'.join(app.__name__.split('.')[:-1])

        if app_name in BUILTIN_SEQUENCES:
            module_name = 'django_evolution.builtin_evolutions'
        else:
            module_name = '%s.evolutions' % app_name

        evolution_module = __import__(module_name, {}, {}, [''])
    except ImportError:
        return []

    mutations = []

    for label in evolution_labels:
        directory_name = os.path.dirname(evolution_module.__file__)

        # The first element is used for compatibility purposes.
        filenames = [
            os.path.join(directory_name, label + '.sql'),
            os.path.join(directory_name, "%s_%s.sql" % (database, label)),
        ]

        found = False

        for filename in filenames:
            if os.path.exists(filename):
                sql = []
                sql_file = open(sql_file_name)

                for line in sql_file:
                    sql.append(line)

                mutations.append(SQLMutation(label, sql))

                found = True
                break

        if not found:
            try:
                module_name = [evolution_module.__name__, label]
                module = __import__('.'.join(module_name), {}, {},
                                    [module_name])
                mutations.extend(module.MUTATIONS)
            except ImportError:
                raise EvolutionException(
                    'Error: Failed to find an SQL or Python evolution named %s'
                    % label)

    if is_multi_db():
        latest_version = Version.objects.using(database).latest('when')
    else:
        latest_version = Version.objects.latest('when')

    app_label = app.__name__.split('.')[-2]
    old_proj_sig = pickle.loads(str(latest_version.signature))
    proj_sig = create_project_sig(database)

    if app_label in old_proj_sig and app_label in proj_sig:
        # We want to go through now and make sure we're only applying
        # evolutions for models where the signature is different between
        # what's stored and what's current.
        #
        # The reason for this is that we may have just installed a baseline,
        # which would have the up-to-date signature, and we might be trying
        # to apply evolutions on top of that (which would already be applied).
        # These would generate errors. So, try hard to prevent that.
        old_app_sig = old_proj_sig[app_label]
        app_sig = proj_sig[app_label]

        changed_models = set()

        # Find the list of models in the latest signature of this app
        # that aren't in the old signature.
        for model_name, model_sig in app_sig.iteritems():
            if (model_name not in old_app_sig
                    or old_app_sig[model_name] != model_sig):
                changed_models.add(model_name)

        # Now do the same for models in the old signature, in case the
        # model has been deleted.
        for model_name, model_sig in old_app_sig.iteritems():
            if model_name not in app_sig:
                changed_models.add(model_name)

        # We should now have a full list of which models changed. Filter
        # the list of mutations appropriately.
        mutations = [
            mutation for mutation in mutations
            if (not hasattr(mutation, 'model_name')
                or mutation.model_name in changed_models)
        ]

    return mutations
示例#4
0
    def __init__(self, original, current):
        self.original_sig = original
        self.current_sig = current

        self.changed = {}
        self.deleted = {}

        if self.original_sig.get('__version__', 1) != 1:
            raise EvolutionException(
                "Unknown version identifier in original signature: %s",
                self.original_sig['__version__'])

        if self.current_sig.get('__version__', 1) != 1:
            raise EvolutionException(
                "Unknown version identifier in target signature: %s",
                self.current_sig['__version__'])

        for app_name, old_app_sig in original.items():
            if app_name == '__version__':
                # Ignore the __version__ tag
                continue

            new_app_sig = self.current_sig.get(app_name, None)

            if new_app_sig is None:
                # App has been deleted
                self.deleted[app_name] = old_app_sig.keys()
                continue

            for model_name, old_model_sig in old_app_sig.items():
                new_model_sig = new_app_sig.get(model_name, None)

                if new_model_sig is None:
                    # Model has been deleted
                    self.changed.setdefault(app_name,
                        {}).setdefault('deleted',
                        []).append(model_name)
                    continue

                old_fields = old_model_sig['fields']
                new_fields = new_model_sig['fields']

                # Look for deleted or modified fields
                for field_name, old_field_data in old_fields.items():
                    new_field_data = new_fields.get(field_name, None)

                    if new_field_data is None:
                        # Field has been deleted
                        self.changed.setdefault(app_name,
                            {}).setdefault('changed',
                            {}).setdefault(model_name,
                            {}).setdefault('deleted',
                            []).append(field_name)
                        continue

                    properties = set(old_field_data.keys())
                    properties.update(new_field_data.keys())

                    for prop in properties:
                        old_value = old_field_data.get(prop,
                            ATTRIBUTE_DEFAULTS.get(prop, None))
                        new_value = new_field_data.get(prop,
                            ATTRIBUTE_DEFAULTS.get(prop, None))

                        if old_value != new_value:
                            try:
                                if (prop == 'field_type' and
                                    (old_value().get_internal_type() ==
                                     new_value().get_internal_type())):
                                    continue
                            except TypeError:
                                pass

                            # Field has been changed
                            self.changed.setdefault(app_name,
                                {}).setdefault('changed',
                                {}).setdefault(model_name,
                                {}).setdefault('changed',
                                {}).setdefault(field_name,[]).append(prop)

                # Look for added fields
                new_fields = new_model_sig['fields']

                for field_name, new_field_data in new_fields.items():
                    old_field_data = old_fields.get(field_name, None)

                    if old_field_data is None:
                        self.changed.setdefault(app_name,
                            {}).setdefault('changed',
                            {}).setdefault(model_name,
                            {}).setdefault('added',
                            []).append(field_name)
示例#5
0
 def __call__(self):
     raise EvolutionException(
         "Cannot use hinted evolution: AddField or ChangeField mutation "
         "for '%s.%s' in '%s' requires user-specified initial value."
         % (self.model, self.field, self.app))