def METHOD_NAME(self, base_revision, target_revision,
                      setup_thd_cb, verify_thd_cb):
    def setup_thd(conn):
        metadata = sa.MetaData()
        table = sautils.Table(
            'alembic_version', metadata,
            sa.Column("version_num", sa.String(32), nullable=False),
        )
        table.create(bind=conn)
        conn.execute(table.insert(), version_num=base_revision)
        setup_thd_cb(conn)
    yield self.db.pool.do(setup_thd)
    alembic_scripts = self.db.model.alembic_get_scripts()
    def upgrade_thd(engine):
        with querylog.log_queries():
            with sautils.withoutSqliteForeignKeys(engine):
                with engine.connect() as conn:
                    def upgrade(rev, context):
                        log.msg(f'Upgrading from {rev} to {target_revision}')
                        return alembic_scripts._upgrade_revs(target_revision, rev)
                    context = MigrationContext.configure(conn, opts={'fn': upgrade})
                    with Operations.context(context):
                        with context.begin_transaction():
                            context.run_migrations()
    yield self.db.pool.do_with_engine(upgrade_thd)
    def check_table_charsets_thd(engine):
        # charsets are only a problem for MySQL
        if engine.dialect.name != 'mysql':
            return
        dbs = [r[0] for r in engine.execute("show tables")]
        for tbl in dbs:
            r = engine.execute(f"show create table {tbl}")
            create_table = r.fetchone()[1]
            self.assertIn('DEFAULT CHARSET=utf8', create_table,
                          f"table {tbl} does not have the utf8 charset")
    yield self.db.pool.do(check_table_charsets_thd)
    def verify_thd(engine):
        with sautils.withoutSqliteForeignKeys(engine):
            verify_thd_cb(engine)
    yield self.db.pool.do(verify_thd)