コード例 #1
0
    def test_add_fields_simulation_functions(self):
        """Testing SQLMutation and adding fields with simulation functions"""
        def update_first_two(app_label, proj_sig):
            app_sig = proj_sig[app_label]
            model_sig = app_sig['TestModel']
            model_sig['fields']['added_field1'] = {
                'field_type': models.IntegerField,
                'null': True
            }
            model_sig['fields']['added_field2'] = {
                'field_type': models.IntegerField,
                'null': True
            }

        def update_third(app_label, proj_sig):
            app_sig = proj_sig[app_label]
            model_sig = app_sig['TestModel']
            model_sig['fields']['added_field3'] = {
                'field_type': models.IntegerField,
                'null': True
            }

        self.perform_evolution_tests(AddFieldsModel, [
            SQLMutation('first-two-fields',
                        self.get_sql_mapping('AddFirstTwoFields').split('\n'),
                        update_first_two),
            SQLMutation('third-field',
                        self.get_sql_mapping('AddThirdField').split('\n'),
                        update_third),
        ], ("In model tests.TestModel:\n"
            "    Field 'added_field1' has been added\n"
            "    Field 'added_field3' has been added\n"
            "    Field 'added_field2' has been added"),
                                     sql_name='SQLMutationOutput')
コード例 #2
0
    def test_add_fields_bad_update_func_signature(self):
        """Testing SQLMutation and bad update_func signature"""
        mutation = SQLMutation('test', '', update_func=lambda a, b, c: None)

        message = ('SQLMutations must provide an update_func(simulation) or '
                   'legacy update_func(app_label, project_sig) parameter in '
                   'order to be simulated.')

        with self.assertRaisesMessage(CannotSimulate, message):
            mutation.run_simulation(app_label='tests',
                                    project_sig=ProjectSignature(),
                                    database_state=None)
コード例 #3
0
    def test_add_fields_bad_update_func_signature(self):
        """Testing SQLMutation and bad update_func signature"""
        mutation = SQLMutation('test', '', update_func=lambda a, b, c: None)

        message = (
            'SQLMutations must provide an update_func(simulation) or '
            'legacy update_func(app_label, project_sig) parameter in '
            'order to be simulated.'
        )

        with self.assertRaisesMessage(CannotSimulate, message):
            mutation.run_simulation(app_label='tests',
                                    project_sig=ProjectSignature(),
                                    database_state=None)
コード例 #4
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)
コード例 #5
0
ファイル: evolve.py プロジェクト: Natedeploys/Birdlist
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
コード例 #6
0
 def test_add_fields_cannot_simulate(self):
     """Testing SQLMutation and adding fields cannot be simulated"""
     self.assertRaisesMessage(
         CannotSimulate, 'Cannot simulate SQLMutations',
         lambda: self.perform_evolution_tests(AddFieldsModel, [
             SQLMutation('first-two-fields', [
                 'ALTER TABLE "tests_testmodel" ADD COLUMN'
                 ' "added_field1" integer NULL;',
                 'ALTER TABLE "tests_testmodel" ADD COLUMN'
                 ' "added_field2" integer NULL;'
             ]),
             SQLMutation('third-field', [
                 'ALTER TABLE "tests_testmodel" ADD COLUMN'
                 ' "added_field3" integer NULL;',
             ])
         ], ("In model tests.TestModel:\n"
             "    Field 'added_field1' has been added\n"
             "    Field 'added_field3' has been added\n"
             "    Field 'added_field2' has been added"),
                                              perform_mutations=False))
コード例 #7
0
    def test_add_fields_simulation_functions(self):
        """Testing SQLMutation and adding fields with simulation functions"""

        # Legacy simulation function.
        def update_first_two(app_label, proj_sig):
            app_sig = proj_sig[app_label]
            model_sig = app_sig['TestModel']
            model_sig['fields']['added_field1'] = {
                'field_type': models.IntegerField,
                'null': True
            }
            model_sig['fields']['added_field2'] = {
                'field_type': models.IntegerField,
                'null': True
            }

        # Modern simulation function.
        def update_third(simulation):
            model_sig = simulation.get_model_sig('TestModel')
            model_sig.add_field_sig(
                FieldSignature(field_name='added_field3',
                               field_type=models.IntegerField,
                               field_attrs={
                                   'null': True,
                               }))

        self.perform_evolution_tests(AddFieldsModel, [
            SQLMutation('first-two-fields',
                        self.get_sql_mapping('AddFirstTwoFields'),
                        update_first_two),
            SQLMutation('third-field', self.get_sql_mapping('AddThirdField'),
                        update_third),
        ], ("In model tests.TestModel:\n"
            "    Field 'added_field1' has been added\n"
            "    Field 'added_field2' has been added\n"
            "    Field 'added_field3' has been added"),
                                     sql_name='SQLMutationOutput')
コード例 #8
0
    def test_add_sql_delete(self):
        """Testing pre-processing AddField + SQLMutation + DeleteField"""
        class DestModel(models.Model):
            my_id = models.AutoField(primary_key=True)
            char_field = models.CharField(max_length=20)

        self.perform_evolution_tests(
            DestModel, [
                AddField('TestModel',
                         'added_field',
                         models.CharField,
                         initial='foo',
                         max_length=20),
                SQLMutation('dummy-sql', ['-- Comment --'],
                            lambda app_label, proj_sig: None),
                DeleteField('TestModel', 'added_field'),
            ],
            '', [
                "DeleteField('TestModel', 'char_field')",
            ],
            'add_sql_delete',
            expect_noop=True)
コード例 #9
0
    AddField('ReviewRequest', 'description_rich_text',
             models.BooleanField, initial=False),
    AddField('ReviewRequest', 'testing_done_rich_text',
             models.BooleanField, initial=False),
    AddField('ReviewRequestDraft', 'description_rich_text',
             models.BooleanField, initial=False),
    AddField('ReviewRequestDraft', 'testing_done_rich_text',
             models.BooleanField, initial=False),
    AddField('Review', 'body_top_rich_text',
             models.BooleanField, initial=False),
    AddField('Review', 'body_bottom_rich_text',
             models.BooleanField, initial=False),

    SQLMutation('review_request_rich_text_defaults', ["""
        UPDATE reviews_reviewrequest
           SET description_rich_text = rich_text,
               testing_done_rich_text = rich_text;
    """]),

    SQLMutation('review_request_draft_rich_text_defaults', ["""
        UPDATE reviews_reviewrequestdraft
           SET description_rich_text = rich_text,
               testing_done_rich_text = rich_text;
    """]),

    SQLMutation('review_rich_text_defaults', ["""
        UPDATE reviews_review
           SET body_top_rich_text = rich_text,
               body_bottom_rich_text = rich_text;
    """]),
]
コード例 #10
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
コード例 #11
0
def get_app_mutations(app, evolution_labels=None, database=DEFAULT_DB_ALIAS):
    """Return the mutations on an app provided by the given evolution names.

    Args:
        app (module):
            The app the evolutions belong to.

        evolution_labels (list of unicode, optional):
            The labels of the evolutions to return mutations for.

            If ``None``, this will factor in all evolution labels for the
            app.

        database (unicode, optional):
            The name of the database the evolutions cover.

    Returns:
        list of django_evolution.mutations.BaseMutation:
        The list of mutations provided by the evolutions.

    Raises:
        django_evolution.errors.EvolutionException:
            One or more evolutions are missing.
    """
    # Avoids a nasty circular import. Util modules should always be
    # importable, so we compensate here.
    from django_evolution.mutations import SQLMutation

    evolutions_module = get_evolutions_module(app)

    if evolutions_module is None:
        return []

    mutations = []
    directory_name = os.path.dirname(evolutions_module.__file__)

    if evolution_labels is None:
        evolution_labels = get_evolution_sequence(app)

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

        found = False

        for filename in filenames:
            if os.path.exists(filename):
                with open(filename, 'r') as fp:
                    sql = fp.readlines()

                mutations.append(SQLMutation(label, sql))

                found = True
                break

        if not found:
            try:
                module = get_evolution_module(app=app, evolution_label=label)
                mutations += getattr(module, 'MUTATIONS', [])
            except ImportError:
                raise EvolutionException(
                    'Error: Failed to find an SQL or Python evolution named %s'
                    % label)

    return mutations
コード例 #12
0
from __future__ import unicode_literals

from django.db import models
from django_evolution.mutations import AddField, SQLMutation

MUTATIONS = [
    AddField('ReviewRequest',
             'shipit_count',
             models.IntegerField,
             initial=0,
             null=True),
    SQLMutation('populate_shipit_count', [
        """
        UPDATE reviews_reviewrequest
           SET shipit_count = (
               SELECT COUNT(*)
                 FROM reviews_review
                WHERE reviews_review.review_request_id =
                      reviews_reviewrequest.id
                  AND reviews_review.public
                  AND reviews_review.ship_it
                  AND reviews_review.base_reply_to_id is NULL)
"""
    ])
]
コード例 #13
0
from __future__ import unicode_literals

from django.conf import settings
from django_evolution.mutations import ChangeField, SQLMutation

if settings.DATABASES['default']['ENGINE'].endswith('mysql'):
    field_index_suffix = '(255)'
else:
    field_index_suffix = ''

index_sql = (
    'CREATE INDEX reviews_reviewrequest_summary ON reviews_reviewrequest'
    ' (summary%s);' % field_index_suffix)

MUTATIONS = [
    ChangeField('ReviewRequest', 'summary', initial=None, db_index=False),
    SQLMutation('reviewrequest_summary', [index_sql]),
]
コード例 #14
0
from __future__ import unicode_literals

from django.db import models
from django_evolution.mutations import AddField, SQLMutation

MUTATIONS = [
    AddField('ReviewRequest',
             'last_review_timestamp',
             models.DateTimeField,
             null=True),
    SQLMutation('populate_last_review_timestamp', [
        """
        UPDATE reviews_reviewrequest
           SET last_review_timestamp = (
               SELECT reviews_review.timestamp
                 FROM reviews_review
                WHERE reviews_review.review_request_id =
                      reviews_reviewrequest.id
                  AND reviews_review.public
                ORDER BY reviews_review.timestamp DESC
                LIMIT 1)
"""
    ])
]
コード例 #15
0
from django_evolution.mutations import SQLMutation

MUTATIONS = [
    SQLMutation('mysql_fields_changed_longtext', [
        """
        ALTER TABLE changedescs_changedescription
             MODIFY fields_changed LONGTEXT;
"""
    ])
]