[Asterisk-code-review] alembic: Allow cdr, config and voicemail to exist in the sa... (asterisk[13])

George Joseph asteriskteam at digium.com
Tue Oct 4 17:26:15 CDT 2016


George Joseph has uploaded a new change for review.

  https://gerrit.asterisk.org/4018

Change subject: alembic:  Allow cdr, config and voicemail to exist in the same schema
......................................................................

alembic:  Allow cdr, config and voicemail to exist in the same schema

cdr, config and voicemail are all separate alembic trees.  Because
alembic's default is to use a table named 'alembic_version' to store
the current tree revision, the 3 trees can't exist in the same schema
without stepping on each other.

Now each tree uses 'alembic_version_<tree_name>' as the version table.
Each tree's env.py script now first checks for 'alembic_version'.  If
it finds it AND its revision is in the tree's history, the script
renames it to 'alembic_version_<tree_name>'.  Regardless, the script
then continues with the migration using 'alembic_version_<tree_name>'
and creates that table if it's not found.  The result is that if an
existing 'alembic_version' table was found but it didn't belong to this
tree, it's left alone and 'alembic_version_<tree_name>' is used or
created.

WARNING:  If multiple trees are using the same schema, they MUST NOT
CRU or D any objects with names that might exist in the other trees.
An example would be 'yesno_values' type.  If two trees perform
operations on it, one tree could pull it out from under the other.
Thankfully we currently don't share any names among cdr, config and
voicemail.

ASTERISK-24311 #close
Reported-by: Dafi Ni

Change-Id: I4d593f000350deb5d21a14fa1e9bc3896844d898
---
M contrib/ast-db-manage/cdr/env.py
M contrib/ast-db-manage/config/env.py
M contrib/ast-db-manage/voicemail/env.py
3 files changed, 168 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/18/4018/1

diff --git a/contrib/ast-db-manage/cdr/env.py b/contrib/ast-db-manage/cdr/env.py
index 6740d59..94d1b50 100755
--- a/contrib/ast-db-manage/cdr/env.py
+++ b/contrib/ast-db-manage/cdr/env.py
@@ -1,7 +1,10 @@
 from __future__ import with_statement
 from alembic import context
+from alembic.script import ScriptDirectory
+from alembic.operations import Operations
 from sqlalchemy import engine_from_config, pool
 from logging.config import fileConfig
+import logging
 
 # this is the Alembic Config object, which provides
 # access to the values within the .ini file in use.
@@ -14,6 +17,7 @@
 except:
     pass
 
+logger = logging.getLogger('alembic.runtime.setup')
 # add your model's MetaData object here
 # for 'autogenerate' support
 # from myapp import mymodel
@@ -55,11 +59,61 @@
                 prefix='sqlalchemy.',
                 poolclass=pool.NullPool)
 
+    logger.info('Testing for an old alembic_version table.')
+
     connection = engine.connect()
     context.configure(
                 connection=connection,
-                target_metadata=target_metadata
+                target_metadata=target_metadata,
+                version_table='alembic_version'
                 )
+
+    script_location = config.get_main_option('script_location')
+    found = False
+    mc = context.get_context()
+    current_db_revision = mc.get_current_revision()
+    script = ScriptDirectory.from_config(config)
+    """ If there was an existing alembic_version table, we we need to
+    check that it's current revision is in the history for the tree we're
+    working with.
+    """
+    for x in script.iterate_revisions('head', 'base'):
+        if x.revision == current_db_revision:
+            """ An alembic_versions table was found and it belongs to this alembic tree """
+            logger.info('An old alembic_version table at revision %s was found for %s.  Renaming to alembic_version_%s.',
+                        current_db_revision, script_location, script_location)
+            op = Operations(mc)
+            try:
+                with context.begin_transaction():
+                    op.rename_table('alembic_version', 'alembic_version_%s' % script_location)
+                found = True
+            except:
+                logger.error('Unable to rename alembic_version to alembic_version_%s.',
+                            script_location)
+                connection.close()
+                return
+
+            break
+
+    if not found:
+        logger.info('Didn\'t find an old alembic_version table.  Good.')
+    logger.info('Trying alembic_version_%s.' % script_location)
+
+    """ We MAY have an alembic_version table that doesn't belong to this tree but if
+    we still don't have an alembic_version_<tree> table, alembic will create it.
+    """
+    context.configure(
+                connection=connection,
+                target_metadata=target_metadata,
+                version_table='alembic_version_' + script_location
+                )
+    mc = context.get_context()
+    current_db_revision = mc.get_current_revision()
+    if current_db_revision:
+        logger.info('Using the alembic_version_%s table at revision %s.',
+                    script_location, current_db_revision)
+    else:
+        logger.info('Creating new alembic_version_%s table.', script_location)
 
     try:
         with context.begin_transaction():
@@ -67,6 +121,7 @@
     finally:
         connection.close()
 
+
 if context.is_offline_mode():
     run_migrations_offline()
 else:
diff --git a/contrib/ast-db-manage/config/env.py b/contrib/ast-db-manage/config/env.py
index 6740d59..94d1b50 100755
--- a/contrib/ast-db-manage/config/env.py
+++ b/contrib/ast-db-manage/config/env.py
@@ -1,7 +1,10 @@
 from __future__ import with_statement
 from alembic import context
+from alembic.script import ScriptDirectory
+from alembic.operations import Operations
 from sqlalchemy import engine_from_config, pool
 from logging.config import fileConfig
+import logging
 
 # this is the Alembic Config object, which provides
 # access to the values within the .ini file in use.
@@ -14,6 +17,7 @@
 except:
     pass
 
+logger = logging.getLogger('alembic.runtime.setup')
 # add your model's MetaData object here
 # for 'autogenerate' support
 # from myapp import mymodel
@@ -55,11 +59,61 @@
                 prefix='sqlalchemy.',
                 poolclass=pool.NullPool)
 
+    logger.info('Testing for an old alembic_version table.')
+
     connection = engine.connect()
     context.configure(
                 connection=connection,
-                target_metadata=target_metadata
+                target_metadata=target_metadata,
+                version_table='alembic_version'
                 )
+
+    script_location = config.get_main_option('script_location')
+    found = False
+    mc = context.get_context()
+    current_db_revision = mc.get_current_revision()
+    script = ScriptDirectory.from_config(config)
+    """ If there was an existing alembic_version table, we we need to
+    check that it's current revision is in the history for the tree we're
+    working with.
+    """
+    for x in script.iterate_revisions('head', 'base'):
+        if x.revision == current_db_revision:
+            """ An alembic_versions table was found and it belongs to this alembic tree """
+            logger.info('An old alembic_version table at revision %s was found for %s.  Renaming to alembic_version_%s.',
+                        current_db_revision, script_location, script_location)
+            op = Operations(mc)
+            try:
+                with context.begin_transaction():
+                    op.rename_table('alembic_version', 'alembic_version_%s' % script_location)
+                found = True
+            except:
+                logger.error('Unable to rename alembic_version to alembic_version_%s.',
+                            script_location)
+                connection.close()
+                return
+
+            break
+
+    if not found:
+        logger.info('Didn\'t find an old alembic_version table.  Good.')
+    logger.info('Trying alembic_version_%s.' % script_location)
+
+    """ We MAY have an alembic_version table that doesn't belong to this tree but if
+    we still don't have an alembic_version_<tree> table, alembic will create it.
+    """
+    context.configure(
+                connection=connection,
+                target_metadata=target_metadata,
+                version_table='alembic_version_' + script_location
+                )
+    mc = context.get_context()
+    current_db_revision = mc.get_current_revision()
+    if current_db_revision:
+        logger.info('Using the alembic_version_%s table at revision %s.',
+                    script_location, current_db_revision)
+    else:
+        logger.info('Creating new alembic_version_%s table.', script_location)
 
     try:
         with context.begin_transaction():
@@ -67,6 +121,7 @@
     finally:
         connection.close()
 
+
 if context.is_offline_mode():
     run_migrations_offline()
 else:
diff --git a/contrib/ast-db-manage/voicemail/env.py b/contrib/ast-db-manage/voicemail/env.py
index 6740d59..94d1b50 100755
--- a/contrib/ast-db-manage/voicemail/env.py
+++ b/contrib/ast-db-manage/voicemail/env.py
@@ -1,7 +1,10 @@
 from __future__ import with_statement
 from alembic import context
+from alembic.script import ScriptDirectory
+from alembic.operations import Operations
 from sqlalchemy import engine_from_config, pool
 from logging.config import fileConfig
+import logging
 
 # this is the Alembic Config object, which provides
 # access to the values within the .ini file in use.
@@ -14,6 +17,7 @@
 except:
     pass
 
+logger = logging.getLogger('alembic.runtime.setup')
 # add your model's MetaData object here
 # for 'autogenerate' support
 # from myapp import mymodel
@@ -55,11 +59,61 @@
                 prefix='sqlalchemy.',
                 poolclass=pool.NullPool)
 
+    logger.info('Testing for an old alembic_version table.')
+
     connection = engine.connect()
     context.configure(
                 connection=connection,
-                target_metadata=target_metadata
+                target_metadata=target_metadata,
+                version_table='alembic_version'
                 )
+
+    script_location = config.get_main_option('script_location')
+    found = False
+    mc = context.get_context()
+    current_db_revision = mc.get_current_revision()
+    script = ScriptDirectory.from_config(config)
+    """ If there was an existing alembic_version table, we we need to
+    check that it's current revision is in the history for the tree we're
+    working with.
+    """
+    for x in script.iterate_revisions('head', 'base'):
+        if x.revision == current_db_revision:
+            """ An alembic_versions table was found and it belongs to this alembic tree """
+            logger.info('An old alembic_version table at revision %s was found for %s.  Renaming to alembic_version_%s.',
+                        current_db_revision, script_location, script_location)
+            op = Operations(mc)
+            try:
+                with context.begin_transaction():
+                    op.rename_table('alembic_version', 'alembic_version_%s' % script_location)
+                found = True
+            except:
+                logger.error('Unable to rename alembic_version to alembic_version_%s.',
+                            script_location)
+                connection.close()
+                return
+
+            break
+
+    if not found:
+        logger.info('Didn\'t find an old alembic_version table.  Good.')
+    logger.info('Trying alembic_version_%s.' % script_location)
+
+    """ We MAY have an alembic_version table that doesn't belong to this tree but if
+    we still don't have an alembic_version_<tree> table, alembic will create it.
+    """
+    context.configure(
+                connection=connection,
+                target_metadata=target_metadata,
+                version_table='alembic_version_' + script_location
+                )
+    mc = context.get_context()
+    current_db_revision = mc.get_current_revision()
+    if current_db_revision:
+        logger.info('Using the alembic_version_%s table at revision %s.',
+                    script_location, current_db_revision)
+    else:
+        logger.info('Creating new alembic_version_%s table.', script_location)
 
     try:
         with context.begin_transaction():
@@ -67,6 +121,7 @@
     finally:
         connection.close()
 
+
 if context.is_offline_mode():
     run_migrations_offline()
 else:

-- 
To view, visit https://gerrit.asterisk.org/4018
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4d593f000350deb5d21a14fa1e9bc3896844d898
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: George Joseph <gjoseph at digium.com>



More information about the asterisk-code-review mailing list