Esempio n. 1
0
    def make_update_script_for_model(cls, engine, oldmodel,
                                     model, repository, **opts):
        """Create a migration script"""
        
        # Compute differences.
        if isinstance(repository, basestring):
            # oh dear, an import cycle!
            from migrate.versioning.repository import Repository
            repository = Repository(repository)
        oldmodel = load_model(oldmodel)
        model = load_model(model)
        diff = schemadiff.getDiffOfModelAgainstModel(
            oldmodel,
            model,
            engine,
            excludeTables=[repository.version_table])
        decls, upgradeCommands, downgradeCommands = \
            genmodel.ModelGenerator(diff).toUpgradeDowngradePython()

        # Store differences into file.
        template_file = None
        src = template.get_script(template_file)
        contents = open(src).read()
        search = 'def upgrade():'
        contents = contents.replace(search, '\n\n'.join((decls, search)), 1)
        if upgradeCommands:
            contents = contents.replace('    pass', upgradeCommands, 1)
        if downgradeCommands:
            contents = contents.replace('    pass', downgradeCommands, 1)
        return contents
Esempio n. 2
0
def commit_db_model(db_uri, db_repo, model_dotted_name, commit_msg):
    logger.info(
        "Committing new change on model : {}".format(model_dotted_name))

    # Test if the migrate repository exists
    if not os.path.isdir(db_repo):
        raise OSError(2, "Migrate repository doesn't exists ! ", db_repo)

    new_model = load_model(model_dotted_name)

    # Display detected changes to user
    print("------------------------------")
    print(mapi.compare_model_to_db(db_uri, db_repo, new_model))
    print("------------------------------")
    if not confirm(
            "Are these changes correct (ignored tables {} are listed here but will be ignored ) ?"
            .format(IGNORED_TABLES)):
        logger.info("Changes not confirmed aborting :(")
        return

    with TemporaryDirectory(prefix="OPVDBMigrate") as temp_dir:
        sys.path.append(temp_dir)  # Used to read generated python
        old_model_fpath = Path(temp_dir) / "oldmodel.py"

        # generating old model from database
        logger.info("Generated old model python script from database")
        old_model_source = mapi.create_model(db_uri, db_repo)
        logger.debug("Old model python : \n {}".format(old_model_source))
        old_model_source = correction_geography(old_model_source)
        save_to_file(old_model_source, old_model_fpath)

        # get latest version
        new_version = mapi.version(db_repo) + 1
        update_script_path = Path(
            db_repo) / "versions" / get_update_script_name(
                new_version, commit_msg)
        logger.debug("Lastest version in repository {} is {}".format(
            db_repo, new_version))

        # make_update_script_for_model, save it in repo lastest_version + 1 + commit msg
        oldmodel = load_model('oldmodel:meta')
        oldmodel = filter_tables(oldmodel, IGNORED_TABLES)
        update_script_source = mapi.make_update_script_for_model(
            db_uri, db_repo, oldmodel, new_model)
        print(update_script_source)
        input("Wait ... ")
        save_to_file(update_script_source, update_script_path)

        if confirm(
                "Did you check (and modify if necessary) the upgrade script ({}) ? !! Confirm will upgrade the database !!"
                .format(update_script_path)):
            logger.info("Upgrading the database")
            # upgrade
            mapi.upgrade(db_uri, db_repo)
            logger.info("Migration done and versionned :) ")
        else:
            logger.info("Removing the update script")
            os.unlink(update_script_path)
Esempio n. 3
0
    def make_update_script_for_model(cls, engine, oldmodel,
                                     model, repository, **opts):
        """Create a migration script based on difference between two SA models.

        :param repository: path to migrate repository
        :param oldmodel: dotted.module.name:SAClass or SAClass object
        :param model: dotted.module.name:SAClass or SAClass object
        :param engine: SQLAlchemy engine
        :type repository: string or :class:`Repository instance <migrate.versioning.repository.Repository>`
        :type oldmodel: string or Class
        :type model: string or Class
        :type engine: Engine instance
        :returns: Upgrade / Downgrade script
        :rtype: string
        """

        if isinstance(repository, basestring):
            # oh dear, an import cycle!
            from migrate.versioning.repository import Repository
            repository = Repository(repository)

        oldmodel = load_model(oldmodel)
        model = load_model(model)

        # Compute differences.
        diff = schemadiff.getDiffOfModelAgainstModel(
            model,
            oldmodel,
            excludeTables=[repository.version_table])
        # TODO: diff can be False (there is no difference?)
        decls, upgradeCommands, downgradeCommands = \
            genmodel.ModelGenerator(diff,engine).genB2AMigration()

        # Store differences into file.
        src = Template(opts.pop('templates_path', None)).get_script(opts.pop('templates_theme', None))
        f = open(src)
        contents = f.read()
        f.close()

        # generate source
        search = 'def upgrade(migrate_engine):'
        contents = contents.replace(search, '\n\n'.join((decls, search)), 1)
        if upgradeCommands:
            contents = contents.replace('    pass', upgradeCommands, 1)
        if downgradeCommands:
            contents = contents.replace('    pass', downgradeCommands, 1)
        return contents
Esempio n. 4
0
    def make_update_script_for_model(cls, engine, oldmodel, model, repository,
                                     **opts):
        """Create a migration script based on difference between two SA models.

        :param repository: path to migrate repository
        :param oldmodel: dotted.module.name:SAClass or SAClass object
        :param model: dotted.module.name:SAClass or SAClass object
        :param engine: SQLAlchemy engine
        :type repository: string or :class:`Repository instance <migrate.versioning.repository.Repository>`
        :type oldmodel: string or Class
        :type model: string or Class
        :type engine: Engine instance
        :returns: Upgrade / Downgrade script
        :rtype: string
        """

        if isinstance(repository, six.string_types):
            # oh dear, an import cycle!
            from migrate.versioning.repository import Repository
            repository = Repository(repository)

        oldmodel = load_model(oldmodel)
        model = load_model(model)

        # Compute differences.
        diff = schemadiff.getDiffOfModelAgainstModel(
            model, oldmodel, excludeTables=[repository.version_table])
        # TODO: diff can be False (there is no difference?)
        decls, upgradeCommands, downgradeCommands = \
            genmodel.ModelGenerator(diff,engine).genB2AMigration()

        # Store differences into file.
        src = Template(opts.pop('templates_path', None)).get_script(
            opts.pop('templates_theme', None))
        f = open(src)
        contents = f.read()
        f.close()

        # generate source
        search = 'def upgrade(migrate_engine):'
        contents = contents.replace(search, '\n\n'.join((decls, search)), 1)
        if upgradeCommands:
            contents = contents.replace('    pass', upgradeCommands, 1)
        if downgradeCommands:
            contents = contents.replace('    pass', downgradeCommands, 1)
        return contents
Esempio n. 5
0
    def compare_model_to_db(cls, engine, model, repository):
        """
        Compare the current model against the current database.
        """
        if isinstance(repository, basestring):
            repository = Repository(repository)
        model = load_model(model)

        diff = schemadiff.getDiffOfModelAgainstDatabase(model, engine, excludeTables=[repository.version_table])
        return diff
Esempio n. 6
0
 def compare_model_to_db(cls, engine, model, repository):
     """
     Compare the current model against the current database.
     """
     if isinstance(repository, basestring):
         repository = Repository(repository)
     model = load_model(model)
     diff = schemadiff.getDiffOfModelAgainstDatabase(
         model, engine, excludeTables=[repository.version_table])
     return diff
Esempio n. 7
0
    def update_db_from_model(self, model):
        """
        Modify the database to match the structure of the current Python model.
        """
        model = load_model(model)

        diff = schemadiff.getDiffOfModelAgainstDatabase(
            model, self.engine, excludeTables=[self.repository.version_table])
        genmodel.ModelGenerator(diff, self.engine).runB2A()

        self.update_repository_table(self.version, int(self.repository.latest))

        self.load()
Esempio n. 8
0
 def update_db_from_model(self, model):
     """
     Modify the database to match the structure of the current Python model.
     """
     if isinstance(self.repository, basestring):
         self.repository=Repository(self.repository)
     model = load_model(model)
     diff = schemadiff.getDiffOfModelAgainstDatabase(
         model, self.engine, excludeTables=[self.repository.version_table])
     genmodel.ModelGenerator(diff).applyModel()
     update = self.table.update(
         self.table.c.repository_id == str(self.repository.id))
     self.engine.execute(update, version=int(self.repository.latest))
Esempio n. 9
0
 def update_db_from_model(self, model):
     """
     Modify the database to match the structure of the current Python model.
     """
     if isinstance(self.repository, basestring):
         self.repository = Repository(self.repository)
     model = load_model(model)
     diff = schemadiff.getDiffOfModelAgainstDatabase(
         model, self.engine, excludeTables=[self.repository.version_table])
     genmodel.ModelGenerator(diff).applyModel()
     update = self.table.update(
         self.table.c.repository_id == str(self.repository.id))
     self.engine.execute(update, version=int(self.repository.latest))
Esempio n. 10
0
    def update_db_from_model(self, model):
        """
        Modify the database to match the structure of the current Python model.
        """
        model = load_model(model)

        diff = schemadiff.getDiffOfModelAgainstDatabase(
            model, self.engine, excludeTables=[self.repository.version_table])
        genmodel.ModelGenerator(diff).applyModel()

        self.update_repository_table(self.version, int(self.repository.latest))

        self.load()
Esempio n. 11
0
def create_or_migrate(db_uri, db_repo, model_dotted_name):
    """
    Create or migrate a database.

    :param db_uri: Database URI.
    :param db_repo: Migrate repository.
    :param model_dotted_name: path to model in form of string: ``some.python.module:Class`
    """
    logger.info("Create or migrate database: {} with migrate repo: {}".format(
        db_uri, db_repo))

    # Test if the migrate repository exists
    if not os.path.isdir(db_repo):
        raise OSError(2, "Migrate repository doesn't exists ! ", db_repo)

    engine = create_engine(db_uri)

    # if database isn't under versionning, building it or setting correction version
    if not is_under_version_control(db_uri=db_uri, db_repo=db_repo):

        if lastest_unversionned_schemas_deployed(
                engine=engine):  # DB exists is the lastest not versionned
            logger.info(
                "Database {} wasn't versionned but is the latest unversionned schema, setting it's"
                .format(db_uri) + "version to 0, to apply migrations.")
            mapi.version_control(
                db_uri, db_repo,
                0)  # considering it's an old db, before versionning
        else:
            logger.info(
                "Database {} tables doesn't seems to exists, try to create it."
                .format(db_uri))
            meta = load_model(model_dotted_name)
            meta.create_all(engine)

            lastest_version_rep = mapi.version(db_repo)
            logger.debug(
                "Lastest version in repo is {}, setting db to this version".
                format(lastest_version_rep))
            mapi.version_control(db_uri, db_repo, lastest_version_rep)

    # upgrading to newest version
    logger.info("Upgrading database")
    mapi.upgrade(db_uri, db_repo)
def update_pylons_db_from_model(url, model_str, commit=False):
    """update_pylons_db_from_model URL MODEL_STR COMMIT

    Modify the database to match the structure of the current Pylons
    model. 

    NOTE: This is EXPERIMENTAL.
    """  # TODO: get rid of EXPERIMENTAL label
    
    global _debug_messages
    
#    engine = opts.pop('engine')  # relies on @with_engine, and url being first argument
    engine = construct_engine(url) # direct approach
    if _debug_messages:
        print "engine= ", engine
    
    if _debug_messages:
        print "sqlalchemy-migrate-pylons : engine created"
    
    
    model_metadata = load_model(model_str)
    if _debug_messages:
        print "sqlalchemy-migrate-pylons : model metadata loaded from model_str"
    
    #schema.MetaData(engine).bind=model_metadata
    
    #print " Meta Internal: ", model.metadata, "\n"
    #print " Meta Migrate : ", sqlalchemy.MetaData(engine), "\n"
    #model.metadata=sqlalchemy.MetaData(engine)
    #model_metadata = declarative_base(metadata=sqlalchemy.MetaData(engine))
    
    #model_metadata.DBsession.configure(bind=engine, autocommit=False)
    #model_metadata.engine = engine
    
    #model_metadata.reflect(bind=engine)
    
    #declarative_base(metadata=model_metadata)
    #sqlalchemy.MetaData(engine).bind = engine
    
    diff = schemadiff.getDiffOfModelAgainstDatabase(model_metadata, engine)
    print "\n====== sqlalchemy-migrate-pylons : Model vs. Database ======\n", diff, "\n"
    
    if commit:
#        genmodel.ModelGenerator(diff).applyModel()
#        print "\n Engine in Diffs : ", diff.conn.engine, "\n"

        #print " Meta Internal: ", model.session, "\n"
        #print " Meta Migrate : ", sqlalchemy.MetaData(diff.conn.engine), "\n"
        
        #meta = model.metadata 
        #sqlalchemy.MetaData(diff.conn.engine).bind = engine
        #meta.DBsession.configure(bind=engine, autocommit=False)
                
        if hasattr(diff, 'tablesMissingInDatabase'):
            print "MISSING : ", diff.tablesMissingInDatabase
            print "MISSING : ", sqlalchemy.sql.util.sort_tables(diff.tablesMissingInDatabase)
        
            diff.tablesMissingInDatabase = sqlalchemy.sql.util.sort_tables(diff.tablesMissingInDatabase)
            print "====== sqlalchemy-migrate-pylons : Table Creation order : ======\n", diff, "\n"
    
        #sqlalchemy.MetaData(engine).bind = engine

        if hasattr(diff, 'tablesMissingInDatabase'):
            ## Oldrelease...
            newmodel = genmodel.ModelGenerator(diff, declarative=True)
            #newmodel.reflect(bind=engine)
        else:
            # This is a change for new release...
            newmodel = genmodel.ModelGenerator(diff, engine, declarative=True)
        
        if hasattr(diff, 'tablesMissingInDatabase'):
            ## Oldrelease...
            print "====== sqlalchemy-migrate-pylons : Different Model created ======\n"
            print " New Model (in Python): \n\n", newmodel.toUpgradeDowngradePython()[0], "\n"   # Show the Declarations 
            print "# Upgrade Code :\n", newmodel.toUpgradeDowngradePython()[1], "\n"   # Show the Upgrade code
        
        newmodel.applyModel()
        
        print "====== sqlalchemy-migrate-pylons : Database Migrated ======\n"

        diff = schemadiff.getDiffOfModelAgainstDatabase(model_metadata, engine)
        print "\n====== sqlalchemy-migrate-pylons : Model vs. Database (after migration) ======\n", diff, "\n"
        
    if isinstance(engine, Engine):
        engine.dispose()