Пример #1
0
 def assertDiff(isDiff, tablesMissingInDatabase, tablesMissingInModel,
                tablesWithDiff):
     diff = schemadiff.getDiffOfModelAgainstDatabase(
         self.meta, self.engine, excludeTables=['migrate_version'])
     self.assertEqual(
         (diff.tables_missing_from_B, diff.tables_missing_from_A,
          list(diff.tables_different.keys()), bool(diff)),
         (tablesMissingInDatabase, tablesMissingInModel, tablesWithDiff,
          isDiff))
    def create_model(cls, engine, repository, declarative=False, config=None):
        """
        Dump the current database as a Python model.
        """
        if isinstance(repository, six.string_types):
            repository = Repository(repository, config=config)

        diff = schemadiff.getDiffOfModelAgainstDatabase(
            MetaData(), engine, excludeTables=[repository.version_table]
            )
        return genmodel.ModelGenerator(diff, engine, declarative).genBDefinition()
    def compare_model_to_db(cls, engine, model, repository, config=None):
        """
        Compare the current model against the current database.
        """
        if isinstance(repository, six.string_types):
            repository = Repository(repository, config=config)
        model = load_model(model)

        diff = schemadiff.getDiffOfModelAgainstDatabase(
            model, engine, excludeTables=[repository.version_table])
        return diff
    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()
 def _run_diff(self, **kw):
     return schemadiff.getDiffOfModelAgainstDatabase(
         self.meta, self.engine, **kw)
Пример #6
0
    def test_functional(self):
        def assertDiff(isDiff, tablesMissingInDatabase, tablesMissingInModel,
                       tablesWithDiff):
            diff = schemadiff.getDiffOfModelAgainstDatabase(
                self.meta, self.engine, excludeTables=['migrate_version'])
            self.assertEqual(
                (diff.tables_missing_from_B, diff.tables_missing_from_A,
                 list(diff.tables_different.keys()), bool(diff)),
                (tablesMissingInDatabase, tablesMissingInModel, tablesWithDiff,
                 isDiff))

        # Model is defined but database is empty.
        assertDiff(True, [self.table_name], [], [])

        # Check Python upgrade and downgrade of database from updated model.
        diff = schemadiff.getDiffOfModelAgainstDatabase(
            self.meta, self.engine, excludeTables=['migrate_version'])
        decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(
            diff, self.engine).genB2AMigration()

        # Feature test for a recent SQLa feature;
        # expect different output in that case.
        if repr(String()) == 'String()':
            self.assertEqualIgnoreWhitespace(
                decls, '''
            from sqlalchemy_migrate_hotoffthehamster.changeset import schema
            pre_meta = MetaData()
            post_meta = MetaData()
            tmp_schemadiff = Table('tmp_schemadiff', post_meta,
                Column('id', Integer, primary_key=True, nullable=False),
                Column('name', UnicodeText),
                Column('data', UnicodeText),
            )
            ''')
        else:
            self.assertEqualIgnoreWhitespace(
                decls, '''
            from sqlalchemy_migrate_hotoffthehamster.changeset import schema
            pre_meta = MetaData()
            post_meta = MetaData()
            tmp_schemadiff = Table('tmp_schemadiff', post_meta,
                Column('id', Integer, primary_key=True, nullable=False),
                Column('name', UnicodeText(length=None)),
                Column('data', UnicodeText(length=None)),
            )
            ''')

        # Create table in database, now model should match database.
        self._applyLatestModel()
        assertDiff(False, [], [], [])

        # Check Python code gen from database.
        diff = schemadiff.getDiffOfModelAgainstDatabase(
            MetaData(), self.engine, excludeTables=['migrate_version'])
        src = genmodel.ModelGenerator(diff, self.engine).genBDefinition()

        namespace = {}
        six.exec_(src, namespace)

        c1 = Table('tmp_schemadiff', self.meta, autoload=True).c
        c2 = namespace['tmp_schemadiff'].c
        self.compare_columns_equal(c1, c2, ['type'])
        # TODO: get rid of ignoring type

        if not self.engine.name == 'oracle':
            # Add data, later we'll make sure it's still present.
            result = self.engine.execute(self.table.insert(),
                                         id=1,
                                         name=u'mydata')
            dataId = result.inserted_primary_key[0]

        # Modify table in model (by removing it and adding it back to model)
        # Drop column data, add columns data2 and data3.
        self.meta.remove(self.table)
        self.table = Table(
            self.table_name,
            self.meta,
            Column('id', Integer(), primary_key=True),
            Column('name', UnicodeText(length=None)),
            Column('data2', Integer(), nullable=True),
            Column('data3', Integer(), nullable=True),
        )
        assertDiff(True, [], [], [self.table_name])

        # Apply latest model changes and find no more diffs.
        self._applyLatestModel()
        assertDiff(False, [], [], [])

        # Drop column data3, add data4
        self.meta.remove(self.table)
        self.table = Table(
            self.table_name,
            self.meta,
            Column('id', Integer(), primary_key=True),
            Column('name', UnicodeText(length=None)),
            Column('data2', Integer(), nullable=True),
            Column('data4', Float(), nullable=True),
        )
        assertDiff(True, [], [], [self.table_name])

        diff = schemadiff.getDiffOfModelAgainstDatabase(
            self.meta, self.engine, excludeTables=['migrate_version'])
        decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(
            diff, self.engine).genB2AMigration(indent='')

        # decls have changed since genBDefinition
        six.exec_(decls, namespace)
        # migration commands expect a namespace containing migrate_engine
        namespace['migrate_engine'] = self.engine
        # run the migration up and down
        six.exec_(upgradeCommands, namespace)
        assertDiff(False, [], [], [])

        six.exec_(decls, namespace)
        six.exec_(downgradeCommands, namespace)
        assertDiff(True, [], [], [self.table_name])

        six.exec_(decls, namespace)
        six.exec_(upgradeCommands, namespace)
        assertDiff(False, [], [], [])

        if not self.engine.name == 'oracle':
            # Make sure data is still present.
            result = self.engine.execute(
                self.table.select(self.table.c.id == dataId))
            rows = result.fetchall()
            self.assertEqual(len(rows), 1)
            self.assertEqual(rows[0].name, 'mydata')

            # Add data, later we'll make sure it's still present.
            result = self.engine.execute(self.table.insert(),
                                         id=2,
                                         name=u'mydata2',
                                         data2=123)
            dataId2 = result.inserted_primary_key[0]

        # Change column type in model.
        self.meta.remove(self.table)
        self.table = Table(
            self.table_name,
            self.meta,
            Column('id', Integer(), primary_key=True),
            Column('name', UnicodeText(length=None)),
            Column('data2', String(255), nullable=True),
        )

        # XXX test type diff
        return

        assertDiff(True, [], [], [self.table_name])

        # Apply latest model changes and find no more diffs.
        self._applyLatestModel()
        assertDiff(False, [], [], [])

        if not self.engine.name == 'oracle':
            # Make sure data is still present.
            result = self.engine.execute(
                self.table.select(self.table.c.id == dataId2))
            rows = result.fetchall()
            self.assertEqual(len(rows), 1)
            self.assertEqual(rows[0].name, 'mydata2')
            self.assertEqual(rows[0].data2, '123')

            # Delete data, since we're about to make a required column.
            # Not even using sqlalchemy.PassiveDefault helps because we're doing explicit column select.
            self.engine.execute(self.table.delete(), id=dataId)

        if not self.engine.name == 'firebird':
            # Change column nullable in model.
            self.meta.remove(self.table)
            self.table = Table(
                self.table_name,
                self.meta,
                Column('id', Integer(), primary_key=True),
                Column('name', UnicodeText(length=None)),
                Column('data2', String(255), nullable=False),
            )
            assertDiff(True, [], [],
                       [self.table_name])  # TODO test nullable diff

            # Apply latest model changes and find no more diffs.
            self._applyLatestModel()
            assertDiff(False, [], [], [])

            # Remove table from model.
            self.meta.remove(self.table)
            assertDiff(True, [], [self.table_name], [])
Пример #7
0
 def _applyLatestModel(self):
     diff = schemadiff.getDiffOfModelAgainstDatabase(
         self.meta, self.engine, excludeTables=['migrate_version'])
     genmodel.ModelGenerator(diff, self.engine).runB2A()