south / south / migration / __init__.py

Simon Law 2cb595b 







Andrew Godwin a29e90b 
Simon Law 1aa194f 
Simon Law 2cb595b 
Andrew Godwin a29e90b 
Simon Law db4e90c 
Simon Law 6d48cfc 

Andrew Godwin 95077d0 
Simon Law 9be0fe6 
Andrew Godwin 2d05373 
Simon Law db4e90c 
Simon Law d23efcd 

Simon Law 67c7410 
Andrew Godwin 45bbe95 
Simon Law 67c7410 

Andrew Godwin 45bbe95 
Simon Law 67c7410 
Simon Law 9be0fe6 



Simon Law 67c7410 
Simon Law 0e389f7 
Simon Law 9be0fe6 





Andrew Godwin 3b116d6 



Andrew Godwin ea55a4f 
Simon Law 9be0fe6 

Andrew Godwin ea55a4f 



Simon Law 9be0fe6 
Andrew Godwin ea55a4f 













Simon Law 9be0fe6 
Simon Law 2cb595b 
andymccurdy 9653402 
Andrew Godwin 043f5cd 
Simon Law 9be0fe6 
Simon Law 3428bb5 
Andrew Godwin bfbc4c5 
Simon Law 0e389f7 
Andrew Godwin bfbc4c5 
Simon Law 3428bb5 
Simon Law 0e389f7 
Andrew Godwin 043f5cd 
Simon Law 3428bb5 

Andrew Godwin 2867a83 

Simon Law 6073337 
Andrew Godwin 043f5cd 



andymccurdy 9653402 
Andrew Godwin 043f5cd 
Simon Law 3428bb5 
Simon Law 02030e0 













Simon Law 7a04063 
Simon Law 02030e0 
Carl Meyer fe7d447 
Simon Law 02030e0 
Simon Law 7a04063 
Simon Law 02030e0 

Simon Law 9be0fe6 

Simon Law 02030e0 






Simon Law 9be0fe6 
Carl Meyer fe7d447 
Simon Law 02030e0 







Simon Law 9be0fe6 
Carl Meyer fe7d447 
Simon Law 02030e0 

Simon Law 2d1d62d 
Simon Law 02030e0 
Simon Law 2d1d62d 
Simon Law 6d48cfc 
Andrew Godwin b6bcef4 
Simon Law 6d48cfc 
Simon Law 2d1d62d 
Simon Law 6d48cfc 
Simon Law 2d1d62d 

Simon Law 6d48cfc 
Marc Abramowitz 99ba041 







Carl Meyer fe7d447 
Andrew Godwin 8931fef 
Andrew Godwin ec5ae48 
Simon Law 2cb595b 

Andrew Godwin 8931fef 
Andrew Godwin ec5ae48 
Simon Law 2cb595b 

Andrew Godwin 8931fef 
Simon Law 2cb595b 
Andrew Godwin ec5ae48 
Andrew Godwin 3b116d6 


Simon Law 2cb595b 
Luke Plant fe7b752 

Andrew Godwin a29e90b 

Luke Plant fe7b752 

Andrew Godwin a29e90b 
Andrew Godwin 2273d71 


Andrew Godwin 4f86714 

Marc Abramowitz fd9a5bd 
Luke Plant fe7b752 



Marc Abramowitz fd9a5bd 
Luke Plant fe7b752 

Marc Abramowitz fd9a5bd 






Marc Abramowitz 99ba041 

Luke Plant fe7b752 
Marc Abramowitz 99ba041 


Marc Abramowitz fd9a5bd 
Luke Plant fe7b752 

Andrew Godwin ec5ae48 
Simon Law 467e9b8 
Simon Law 2975407 
Simon Law 02030e0 
Simon Law f4033a7 


Andrew Godwin 8931fef 
Andrew Godwin ec5ae48 
Simon Law 2cb595b 
David Gouldin 80f47f7 
Carl Meyer fe7d447 
Simon Law f4033a7 
Simon Law 9be0fe6 
Andrew Godwin ec5ae48 
Simon Law 6d48cfc 
Simon Law 2d1d62d 
Simon Law f4033a7 
Simon Law 2d1d62d 
Andrew Godwin 4f86714 
Simon Law f4033a7 

Andrew Godwin 8931fef 
Duncan Parkes 6edd38f 



Andrew Godwin ab02739 


Andrew Godwin 6e78493 

pydolan b076c35 
Andrew Godwin ab02739 
Andrew Godwin c91e416 
"""
Main migration logic.
"""

import sys

from django.core.exceptions import ImproperlyConfigured

import south.db
from south import exceptions
from south.models import MigrationHistory
from south.db import db, DEFAULT_DB_ALIAS
from south.migration.migrators import (Backwards, Forwards,
                                       DryRunMigrator, FakeMigrator,
                                       LoadInitialDataMigrator)
from south.migration.base import Migration, Migrations
from south.migration.utils import SortedSet
from south.migration.base import all_migrations
from south.signals import pre_migrate, post_migrate


def to_apply(forwards, done):
    return [m for m in forwards if m not in done]

def to_unapply(backwards, done):
    return [m for m in backwards if m in done]

def problems(pending, done):
    last = None
    if not pending:
        raise StopIteration()
    for migration in pending:
        if migration in done:
            last = migration
            continue
        if last and migration not in done:
            yield last, migration

def forwards_problems(pending, done, verbosity):
    """
    Takes the list of linearised pending migrations, and the set of done ones,
    and returns the list of problems, if any.
    """
    return inner_problem_check(problems(reversed(pending), done), done, verbosity)

def backwards_problems(pending, done, verbosity):
    return inner_problem_check(problems(pending, done), done, verbosity)

def inner_problem_check(problems, done, verbosity):
    "Takes a set of possible problems and gets the actual issues out of it."
    result = []
    for last, migration in problems:
        # 'Last' is the last applied migration. Step back from it until we
        # either find nothing wrong, or we find something.
        to_check = list(last.dependencies)
        while to_check:
            checking = to_check.pop()
            if checking not in done:
                # That's bad. Error.
                if verbosity:
                    print (" ! Migration %s should not have been applied "
                           "before %s but was." % (last, checking))
                result.append((last, checking))
            else:
                to_check.extend(checking.dependencies)
    return result

def check_migration_histories(histories, delete_ghosts=False, ignore_ghosts=False):
    "Checks that there's no 'ghost' migrations in the database."
    exists = SortedSet()
    ghosts = []
    for h in histories:
        try:
            m = h.get_migration()
            m.migration()
        except exceptions.UnknownMigration:
            ghosts.append(h)
        except ImproperlyConfigured:
            pass                        # Ignore missing applications
        else:
            exists.add(m)
    if ghosts:
        # They may want us to delete ghosts.
        if delete_ghosts:
            for h in ghosts:
                h.delete()
        elif not ignore_ghosts:
            raise exceptions.GhostMigrations(ghosts)
    return exists

def get_dependencies(target, migrations):
    forwards = list
    backwards = list
    if target is None:
        backwards = migrations[0].backwards_plan
    else:
        forwards = target.forwards_plan
        # When migrating backwards we want to remove up to and
        # including the next migration up in this app (not the next
        # one, that includes other apps)
        migration_before_here = target.next()
        if migration_before_here:
            backwards = migration_before_here.backwards_plan
    return forwards, backwards

def get_direction(target, applied, migrations, verbosity, interactive):
    # Get the forwards and reverse dependencies for this target
    forwards, backwards = get_dependencies(target, migrations)
    # Is the whole forward branch applied?
    problems = None
    forwards = forwards()
    workplan = to_apply(forwards, applied)
    if not workplan:
        # If they're all applied, we only know it's not backwards
        direction = None
    else:
        # If the remaining migrations are strictly a right segment of
        # the forwards trace, we just need to go forwards to our
        # target (and check for badness)
        problems = forwards_problems(forwards, applied, verbosity)
        direction = Forwards(verbosity=verbosity, interactive=interactive)
    if not problems:
        # What about the whole backward trace then?
        backwards = backwards()
        missing_backwards = to_apply(backwards, applied)
        if missing_backwards != backwards:
            # If what's missing is a strict left segment of backwards (i.e.
            # all the higher migrations) then we need to go backwards
            workplan = to_unapply(backwards, applied)
            problems = backwards_problems(backwards, applied, verbosity)
            direction = Backwards(verbosity=verbosity, interactive=interactive)
    return direction, problems, workplan

def get_migrator(direction, db_dry_run, fake, load_initial_data):
    if not direction:
        return direction
    if db_dry_run:
        direction = DryRunMigrator(migrator=direction, ignore_fail=False)
    elif fake:
        direction = FakeMigrator(migrator=direction)
    elif load_initial_data:
        direction = LoadInitialDataMigrator(migrator=direction)
    return direction

def get_unapplied_migrations(migrations, applied_migrations):
    applied_migration_names = ['%s.%s' % (mi.app_name,mi.migration) for mi in applied_migrations]

    for migration in migrations:
        is_applied = '%s.%s' % (migration.app_label(), migration.name()) in applied_migration_names
        if not is_applied:
            yield migration

def migrate_app(migrations, target_name=None, merge=False, fake=False, db_dry_run=False, yes=False, verbosity=0, load_initial_data=False, skip=False, database=DEFAULT_DB_ALIAS, delete_ghosts=False, ignore_ghosts=False, interactive=False):
    app_label = migrations.app_label()

    verbosity = int(verbosity)
    # Fire off the pre-migrate signal
    pre_migrate.send(None, app=app_label)
    
    # If there aren't any, quit quizically
    if not migrations:
        print "? You have no migrations for the '%s' app. You might want some." % app_label
        return
    
    # Load the entire dependency graph
    Migrations.calculate_dependencies()
    
    # Check there's no strange ones in the database
    hist_applied_all = MigrationHistory.objects.filter(applied__isnull=False).order_by('applied')
    hist_applied = hist_applied_all.filter(app_name=app_label)
    # If we're using a different database, use that
    if database != DEFAULT_DB_ALIAS:
        hist_applied_all = hist_applied_all.using(database)
        hist_applied = hist_applied.using(database)
        south.db.db = south.db.dbs[database]
        # We now have to make sure the migrations are all reloaded, as they'll
        # have imported the old value of south.db.db.
        Migrations.invalidate_all_modules()
    
    south.db.db.debug = (verbosity > 1)

    # Evaluate the QuerySets at this point, for clarity
    hist_applied = SortedSet(hist_applied)
    hist_applied_all = SortedSet(hist_applied_all)

    if target_name == 'current-1':
        if len(hist_applied) > 1:
            previous_migration = hist_applied.keys()[-2]
            if verbosity:
                print 'previous_migration: %s (applied: %s)' % (previous_migration.migration, previous_migration.applied)
            target_name = previous_migration.migration
        else:
            if verbosity:
                print 'previous_migration: zero'
            target_name = 'zero'
    elif target_name == 'current+1':
        try:
            first_unapplied_migration = get_unapplied_migrations(migrations, hist_applied).next()
            target_name = first_unapplied_migration.name()
        except StopIteration:
            target_name = None
    
    applied_all = check_migration_histories(hist_applied_all, delete_ghosts, ignore_ghosts)
    applied = SortedSet([m.get_migration() for m in hist_applied])
    
    # Guess the target_name
    target = migrations.guess_migration(target_name)
    if verbosity:
        if target_name not in ('zero', None) and target.name() != target_name:
            print " - Soft matched migration %s to %s." % (target_name,
                                                           target.name())
        print "Running migrations for %s:" % app_label
    
    # Get the forwards and reverse dependencies for this target
    direction, problems, workplan = get_direction(target, applied_all, migrations,
                                                  verbosity, interactive)
    if problems and not (merge or skip):
        raise exceptions.InconsistentMigrationHistory(problems)
    
    # Perform the migration
    migrator = get_migrator(direction, db_dry_run, fake, load_initial_data)
    if migrator:
        migrator.print_title(target)
        success = migrator.migrate_many(target, workplan, database)
        # Finally, fire off the post-migrate signal
        if success:
            post_migrate.send(None, app=app_label)
    else:
        if verbosity:
            # Say there's nothing.
            print '- Nothing to migrate.'
        # If we have initial data enabled, and we're at the most recent
        # migration, do initial data.
        # Note: We use a fake Forwards() migrator here. It's never used really.
        if load_initial_data:
            migrator = LoadInitialDataMigrator(migrator=Forwards(verbosity=verbosity))
            migrator.load_initial_data(target, db=database)
        # Send signal.
        post_migrate.send(None, app=app_label)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.