Example #1
0
 def create_all_migrations(self):
     for database in get_capable_databases():
         statements = get_sql_for_new_models(using=database)
         if len(statements) == 0:
             continue
         
         number = self._get_current_migration_number(database)
         
         db_path = os.path.join(self.path, database)
         if not os.path.exists(db_path):
             os.makedirs(db_path)
         
         path = os.path.join(
             db_path,
             "%s.sql" % (str(number + 1).zfill(4),)
         )
         if os.path.exists(path):
             raise CommandError(
                 "Unable to create %r: File already exists" % path
             )
         
         with open(path, 'w') as fp:
             for s in statements:
                 fp.write(s + '\n')
         
         print "Created new migration: %r" % path
Example #2
0
 def init_nashvegas(self):
     # @@@ make cleaner / check explicitly for model instead of looping over and doing string comparisons
     connection = connections[self.db]
     cursor = connection.cursor()
     all_new = get_sql_for_new_models()
     for s in all_new:
         if "nashvegas_migration" in s:
             cursor.execute(s)
             transaction.commit_unless_managed(using=self.db)
             return
Example #3
0
 def create_migrations(self):
     statements = get_sql_for_new_models(self.args)
     if len(statements) > 0:
         for s in statements:
             print s
Example #4
0
                # want to ignore the exception if the management module exists
                # but raises an ImportError for some reason. The only way we
                # can do this is to check the text of the exception. Note that
                # we're a bit broad in how we check the text, because different
                # Python implementations may not use the same text.
                # CPython uses the text "No module named management"
                # PyPy uses "No module named myproject.myapp.management"
                msg = exc.args[0]
                if not msg.startswith(
                        "No module named") or "management" not in msg:
                    raise

        # @@@ make cleaner / check explicitly for model instead of looping over and doing string comparisons
        connection = connections[self.db]
        cursor = connection.cursor()
        all_new = get_sql_for_new_models()
        for s in all_new:
            if "nashvegas_migration" in s:
                cursor.execute(s)
                transaction.commit_unless_managed(using=self.db)
                return

    def create_migrations(self):
        statements = get_sql_for_new_models(self.args)
        if len(statements) > 0:
            for s in statements:
                print s

    @transaction.commit_manually
    def execute_migrations(self, show_traceback=False):
        migrations = self._filter_down()
Example #5
0
 def create_migrations(self, database):
     statements = get_sql_for_new_models(self.args, using=database)
     if len(statements) > 0:
         for s in statements:
             print s
Example #6
0
 def create_migrations(self):
     statements = get_sql_for_new_models(self.args)
     if len(statements) > 0:
         for s in statements:
             print s
Example #7
0
             # if the "management" module itself is missing -- but we don't
             # want to ignore the exception if the management module exists
             # but raises an ImportError for some reason. The only way we
             # can do this is to check the text of the exception. Note that
             # we're a bit broad in how we check the text, because different
             # Python implementations may not use the same text.
             # CPython uses the text "No module named management"
             # PyPy uses "No module named myproject.myapp.management"
             msg = exc.args[0]
             if not msg.startswith('No module named') or 'management' not in msg:
                 raise
     
     # @@@ make cleaner / check explicitly for model instead of looping over and doing string comparisons
     connection = connections[self.db]
     cursor = connection.cursor()
     all_new = get_sql_for_new_models()
     for s in all_new:
         if "nashvegas_migration" in s:
             cursor.execute(s)
             transaction.commit_unless_managed(using=self.db)
             return
 
 def create_migrations(self):
     statements = get_sql_for_new_models(self.args)
     if len(statements) > 0:
         for s in statements:
             print s
 
 @transaction.commit_manually
 def execute_migrations(self, show_traceback=False):
     migrations = self._filter_down()
Example #8
0
 def create_migrations(self, database):
     statements = get_sql_for_new_models(self.args, using=database)
     if len(statements) > 0:
         for s in statements:
             print s
Example #9
0
class Command(BaseCommand):
    
    option_list = BaseCommand.option_list + (
        make_option("-l", "--list",
                    action="store_true",
                    dest="do_list",
                    default=False,
                    help="Enumerate the list of migrations to execute."),
        make_option("-e", "--execute",
                    action="store_true",
                    dest="do_execute",
                    default=False,
                    help="Execute migrations not in versions table."),
        make_option("-c", "--create",
                    action="store_true",
                    dest="do_create",
                    default=False,
                    help="Generates sql for models that are installed but not "
                         "in your database."),
        make_option("--create-all",
                    action="store_true",
                    dest="do_create_all",
                    default=False,
                    help="Generates sql for models that are installed but not "
                         "in your database."),
        make_option("-s", "--seed",
                    action="store_true",
                    dest="do_seed",
                    default=False,
                    help="Seed nashvegas with migrations that have previously "
                         "been applied in another manner."),
        make_option("-d", "--database",
                    action="append",
                    dest="databases",
                    help="Nominates a database to synchronize."),
        make_option("--noinput",
                    action="store_false",
                    dest="interactive",
                    default=False,
                    help="Tells Django to NOT prompt the user for input of "
                         "any kind."),
        make_option("-p", "--path", dest="path",
                    default=None,
                    help="The path to the database migration scripts."))
    
    help = "Upgrade database."
    
    def _get_rev(self, fpath):
        """
        Get an SCM version number. Try svn and git.
        """
        rev = None
        
        try:
            cmd = ["git", "log", "-n1", "--pretty=format:\"%h\"", fpath]
            rev = Popen(cmd, stdout=PIPE, stderr=PIPE).communicate()[0]
        except:
            pass
        
        if not rev:
            try:
                cmd = ["svn", "info", fpath]
                svninfo = Popen(cmd,
                                stdout=PIPE,
                                stderr=PIPE).stdout.readlines()
                for info in svninfo:
                    tokens = info.split(":")
                    if tokens[0].strip() == "Last Changed Rev":
                        rev = tokens[1].strip()
            except:
                pass
        
        return rev
    
    def _get_current_migration_number(self, database):
        try:
            result = Migration.objects.using(
                database
            ).order_by('-migration_label')[0]
        except IndexError:
            return 0
        match = MIGRATION_NAME_RE.match(result.migration_label)
        return int(match.group(1))
    
    def _get_migration_path(self, db, migration):
        default_exists = os.path.exists(os.path.join(self.path, migration))
        if db == DEFAULT_DB_ALIAS and default_exists:
            migration_path = os.path.join(self.path, migration)
        else:
            migration_path = os.path.join(self.path, db, migration)

        return migration_path
    
    def _execute_migration(self, database, migration, show_traceback=True):
        created_models = set()
        
        with open(migration, "rb") as fp:
            lines = fp.readlines()
        content = "".join(lines)
        
        if migration.endswith(".sql"):
            # TODO: this should support proper comments
            to_execute = "".join(
                [l for l in lines if not l.startswith("### New Model: ")]
            )
            connection = connections[database]
            cursor = connection.cursor()
            
            try:
                cursor.execute(to_execute)
                cursor.close()
            except Exception:
                sys.stdout.write("failed\n")
                if show_traceback:
                    traceback.print_exc()
                raise MigrationError()
            else:
                sys.stdout.write("success\n")
            
            for l in lines:
                if l.startswith("### New Model: "):
                    created_models.add(
                        get_model(
                            *l.replace(
                                "### New Model: ",
                                ""
                            ).strip().split(".")
                        )
                    )
        
        elif migration.endswith(".py"):
            # TODO: python files have no concept of active database
            #       we should probably pass it to migrate()
            module = {}
            execfile(migration, {}, module)
            
            if "migrate" in module and callable(module["migrate"]):
                try:
                    module["migrate"]()
                except Exception:
                    sys.stdout.write("failed\n")
                    if show_traceback:
                        traceback.print_exc()
                    raise MigrationError()
                else:
                    sys.stdout.write("success\n")
        
        Migration.objects.using(database).create(
            migration_label=os.path.split(migration)[-1],
            content=content,
            scm_version=self._get_rev(migration),
        )
        
        return created_models
    
    def init_nashvegas(self):
        # Copied from line 35 of django.core.management.commands.syncdb
        # Import the 'management' module within each installed app, to
        # register dispatcher events.
        for app_name in settings.INSTALLED_APPS:
            try:
                import_module(".management", app_name)
            except ImportError, exc:
                # This is slightly hackish. We want to ignore ImportErrors
                # if the "management" module itself is missing -- but we don't
                # want to ignore the exception if the management module exists
                # but raises an ImportError for some reason. The only way we
                # can do this is to check the text of the exception. Note that
                # we're a bit broad in how we check the text, because
                # different Python implementations may not use the same text.
                # CPython uses the text "No module named management"
                # PyPy uses "No module named myproject.myapp.management"
                msg = exc.args[0]
                if not msg.startswith("No module named") or "management" not in msg:
                    raise
        
        # @@@ make cleaner / check explicitly for model instead of looping
        #     over and doing string comparisons
        databases = self.databases or get_capable_databases()
        for database in databases:
            connection = connections[database]
            cursor = connection.cursor()
            all_new = get_sql_for_new_models(['nashvegas'], using=database)
            for lines in all_new:
                to_execute = "\n".join([
                    l
                    for l in lines.split("\n")
                    if not l.startswith("### New Model: ")
                ])
                if not to_execute:
                    continue
                cursor.execute(to_execute)
                transaction.commit_unless_managed(using=database)
Example #10
0
 def create_migrations(self):
     statements = get_sql_for_new_models()
     if len(statements) > 0:
         print "BEGIN;"
         for s in statements:
             print s