title: Alembic: 'relation "public.alembic_version" does not exist' when using `version_table_schema`
body: <p>I'm writing some custom code for Alembic to keep my database always updated in my dev environment for a project. The project involves a database with the following:</p>
  
  <ul>
  <li>A <code>public</code> schema for shared data</li>
  <li>A single schema per client "database"</li>
  <li>One schema that acts as a <code>prototype</code> for all of the client schemas (orgs)</li>
  </ul>
  
  <p>At this moment, I'm not worried about the multiple client schemas, only keeping the <code>public</code> and <code>prototype</code> schemas up-to-date. My env.py script works great for the <code>public</code> schema, but not <code>prototype</code> because alembic is trying to use the version table from <code>public</code> when working with <code>prototype</code>.</p>
  
  <p>So, I thought I could use the <a href="http://alembic.readthedocs.org/en/latest/api/runtime.html?highlight=version_table_schema#alembic.runtime.environment.EnvironmentContext.configure.params.version_table_schema" rel="nofollow"><code>version_table_schema</code></a> option to maintain one version table in the <code>public</code> schema and one in the <code>prototype</code> schema. However, as soon as I start using that, I get a '<em>relation "public.alembic_version" does not exist</em>' error when I attempt to do the upgrade.</p>
  
  <p>The only difference that I see is that, when I use <code>version_table_schema</code> set to the appropriate schema, the generated revision scripts actually contain a line to <code>op.drop_table('alembic_version')</code>. The line ONLY exists when <code>version_table_schema</code> is in use.</p>
  
  <p>I'm hoping that I'm just missing something minor.</p>
  
  <p>The following are all of the relevant source files for reference. The only external dependency should be the <code>appcontext</code> and <code>getDeclarativeBase</code>. <code>appcontext</code> is just for configuration and is definitely working (The database connection works properly). <code>getDeclarativeBase</code> is a way to dynamically get a declarative base (and related metadata) for a schema. Based on the debug output, that seems to be working correctly as well. The metadata objects themselves are associated with the correct schemas when they are constructed.</p>
  
  <hr>
  
  <p><strong>Wrapper functions for running migrations.</strong> <code>autoMigratePublic()</code> and <code>autoMigrateOrgProto()</code> are the problematic methods in this case</p>
  
  <pre><code>""" A wrapper around Alembic that will assist with database migrations.
  
      Our database system is soemwhat complex to upgrade. There is a public
      schema which we use for shared things (such as authentication and job
      management). Then there is the org prototype.
  
      There are also individual schemas for each client org. These are trickier.
  
      http://stackoverflow.com/a/35211383/703040
  
      Also useful:
  
      https://github.com/zzzeek/alembic/blob/0e3319bb36f1612e41a8d7da5a48ce1ca33a0b2b/alembic/config.py#L476
  """
  
  import logging
  import os
  import time
  
  import alembic.config
  import alembic.util
  
  CONFIG_ORG_PROTO = os.path.join("migrations", "alembic_orgproto.ini")
  CONFIG_PUBLIC = os.path.join("migrations", "alembic_public.ini")
  
  log = logging.getLogger("sys.migrations")
  
  def autoMigratePublic():
      try:
          freezePublic()
      except alembic.util.CommandError:
          log.warn("[public] Problem creating migration revision. Skipping as this sometimes just means that we are working with a new DB.")
      upgradePublic()
      return
  
  def autoMigrateOrgProto():
      try:
          freezeOrgProto()
      except alembic.util.CommandError:
          log.warn("[orgproto] Problem creating migration revision. Skipping as this sometimes just means that we are working with a new DB.")
      upgradeOrgProto()
      return
  
  def freezePublic():
      log.info("[public] Checking the database for revisions...")
      alembicArgs = [
          "--config", CONFIG_PUBLIC,
          "--raiseerr",
          "revision",
          "--autogenerate",
          "--message", "autogenerate {0}".format(makeRevisionName()),
      ]
      runAlembic(alembicArgs)
      return
  
  def freezeOrgProto():
      log.info("[orgproto] Checking the database for revisions...")
      alembicArgs = [
          "--config", CONFIG_ORG_PROTO,
          "--raiseerr",
          "revision",
          "--autogenerate",
          "--message", "autogenerate {0}".format(makeRevisionName()),
      ]
      runAlembic(alembicArgs)
      return
  
  def makeRevisionName():
      return time.strftime('%Y-%m-%d %H:%M:%S')
  
  def upgradePublic():
      log.info("[public] Performing database upgrade...")
      alembicArgs = [
          "--config", CONFIG_PUBLIC,
          "--raiseerr",
          "upgrade",
          "head",
      ]
      runAlembic(alembicArgs)
      return
  
  def upgradeOrgProto():
      log.info("[orgproto] Performing database upgrade...")
      alembicArgs = [
          "--config", CONFIG_ORG_PROTO,
          "--raiseerr",
          "upgrade",
          "head",
      ]
      runAlembic(alembicArgs)
      return
  
  def upgradeOrg(schemaName):
      log.info("[%s] Performing database upgrade...", schemaName)
      alembicArgs = [
          "--config", CONFIG_ORG_PROTO,
          "--raiseerr",
          "upgrade",
          "head",
          "-x", "schema={0}".format(schemaName),
      ]
      runAlembic(alembicArgs)
      return
  
  def runAlembic(args):
      return alembic.config.main(args)
  </code></pre>
  
  <hr>
  
  <p><strong>Class for performing migrations.</strong> This class is referenced in the env.py files</p>
  
  <pre><code>import copy
  import logging
  import os
  import re
  import traceback
  
  from logging.config import fileConfig
  
  from sqlalchemy import create_engine
  
  import core.context.appcontext
  from core.database.declarative import getDeclarativeBase
  
  logging.getLogger("alembic").setLevel(logging.DEBUG)
  
  #==============================================================================
  class Migrator(object):
  
      def __init__(self):
          from alembic import context
          self.context = context
          self.config = context.config
          self.log = logging.getLogger("sys.migrations")
          self.sys = core.context.appcontext.instance()
          self.schema = self.config.get_main_option("schema")
          if self.context.get_x_argument("schema"):
              self.schema = self.context.get_x_argument("schema")
          return
  
      def start(self):
          import core.database.tables  # Make sure the metadata is defined
          if self.context.is_offline_mode():
              self.log.error("[%s] Can't run migrations offline", self.schema)
              return
          self.doMigration()
          return
  
      def doMigration(self):
          targetMetadata = getDeclarativeBase(self.schema).metadata
          engine = create_engine(self.sys.getConnectionUrl(), echo=False)
          self.log.info("[%s] Engine:   %s", self.schema, engine)
          self.log.debug("[%s] Metadata: %s", self.schema, targetMetadata)
          for t in targetMetadata.sorted_tables:
              self.log.debug("    - %s", t)
          conn = engine.connect()
          try:
              self.context.configure(
                  conn,
                  version_table_schema=self.schema,
                  target_metadata=targetMetadata,
                  process_revision_directives=self.process_revision_directives,
              )
              with self.context.begin_transaction():
                  self.context.run_migrations()
          finally:
              conn.close()
          return
  
      def process_revision_directives(self, context, revision, directives):
          """ Used to prevent creating empty migrations
  
              See: http://alembic.readthedocs.org/en/latest/cookbook.html#don-t-generate-empty-migrations-with-autogenerate
          """
          if self.config.cmd_opts.autogenerate:
              script = directives[0]
              if script.upgrade_ops.is_empty():
                  self.log.debug("[%s] Auto-generated migration is empty. No migration file will be created.", self.schema)
                  directives[:] = []
              else:
                  self.log.info("[%s] Creating new auto-generated migration revision.", self.schema)
          return
  </code></pre>
  
  <hr>
  
  <p><strong>Sample <code>env.py</code>.</strong> Both the public and prototype upgrades have the same contents</p>
  
  <pre><code>from migrations.migrator import Migrator
  Migrator().start() 
  </code></pre>
  
  <hr>
  
  <p><strong>Sample config ini</strong> The public and prototype migrations use almost the exact same file</p>
  
  <pre><code># A generic, single database configuration.
  
  [alembic]
  # path to migration scripts
  script_location = migrations/orgproto
  
  # template used to generate migration files
  # file_template = %%(rev)s_%%(slug)s
  
  # max length of characters to apply to the
  # "slug" field
  #truncate_slug_length = 40
  
  # set to 'true' to run the environment during
  # the 'revision' command, regardless of autogenerate
  # revision_environment = false
  
  # set to 'true' to allow .pyc and .pyo files without
  # a source .py file to be detected as revisions in the
  # versions/ directory
  # sourceless = false
  
  # version location specification; this defaults
  # to alembic/versions.  When using multiple version
  # directories, initial revisions must be specified with --version-path
  # version_locations = %(here)s/bar %(here)s/bat alembic/versions
  
  # the output encoding used when revision files
  # are written from script.py.mako
  # output_encoding = utf-8
  
  sqlalchemy.url = &lt;Not Loaded&gt;
  
  schema = orgproto
  </code></pre>
  
  <hr>
  
  <p><strong>Mako File</strong> I'm using the default.</p>
  
  <pre><code>"""${message}
  
  Revision ID: ${up_revision}
  Revises: ${down_revision | comma,n}
  Create Date: ${create_date}
  
  """
  
  # revision identifiers, used by Alembic.
  revision = ${repr(up_revision)}
  down_revision = ${repr(down_revision)}
  branch_labels = ${repr(branch_labels)}
  depends_on = ${repr(depends_on)}
  
  from alembic import op
  import sqlalchemy as sa
  ${imports if imports else ""}
  
  def upgrade():
      ${upgrades if upgrades else "pass"}
  
  
  def downgrade():
      ${downgrades if downgrades else "pass"}
  </code></pre>