[asterisk-commits] alembic: Allow cdr, config and voicemail to exist in the sa... (asterisk[14])
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Oct 9 18:42:49 CDT 2016
Joshua Colp has submitted this change and it was merged.
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.
NOTE: Since the env.py scripts in each tree were identical, a common
env.py has been placed in the ast-db-manage directory and a symlink
to it has been placed in each tree directory.
ASTERISK-24311 #close
Reported-by: Dafi Ni
Change-Id: I4d593f000350deb5d21a14fa1e9bc3896844d898
---
D contrib/ast-db-manage/cdr/env.py
A contrib/ast-db-manage/cdr/env.py
D contrib/ast-db-manage/config/env.py
A contrib/ast-db-manage/config/env.py
A contrib/ast-db-manage/env.py
D contrib/ast-db-manage/voicemail/env.py
A contrib/ast-db-manage/voicemail/env.py
7 files changed, 143 insertions(+), 222 deletions(-)
Approvals:
Mark Michelson: Looks good to me, but someone else must approve
Joshua Colp: Looks good to me, approved; Verified
diff --git a/contrib/ast-db-manage/cdr/env.py b/contrib/ast-db-manage/cdr/env.py
deleted file mode 100755
index 6740d59..0000000
--- a/contrib/ast-db-manage/cdr/env.py
+++ /dev/null
@@ -1,74 +0,0 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
- fileConfig(config.config_file_name)
-except:
- pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
- """Run migrations in 'offline' mode.
-
- This configures the context with just a URL
- and not an Engine, though an Engine is acceptable
- here as well. By skipping the Engine creation
- we don't even need a DBAPI to be available.
-
- Calls to context.execute() here emit the given string to the
- script output.
-
- """
- url = config.get_main_option("sqlalchemy.url")
- context.configure(url=url)
-
- with context.begin_transaction():
- context.run_migrations()
-
-def run_migrations_online():
- """Run migrations in 'online' mode.
-
- In this scenario we need to create an Engine
- and associate a connection with the context.
-
- """
- engine = engine_from_config(
- config.get_section(config.config_ini_section),
- prefix='sqlalchemy.',
- poolclass=pool.NullPool)
-
- connection = engine.connect()
- context.configure(
- connection=connection,
- target_metadata=target_metadata
- )
-
- try:
- with context.begin_transaction():
- context.run_migrations()
- finally:
- connection.close()
-
-if context.is_offline_mode():
- run_migrations_offline()
-else:
- run_migrations_online()
-
diff --git a/contrib/ast-db-manage/cdr/env.py b/contrib/ast-db-manage/cdr/env.py
new file mode 120000
index 0000000..74b15c9
--- /dev/null
+++ b/contrib/ast-db-manage/cdr/env.py
@@ -0,0 +1 @@
+../env.py
\ No newline at end of file
diff --git a/contrib/ast-db-manage/config/env.py b/contrib/ast-db-manage/config/env.py
deleted file mode 100755
index 6740d59..0000000
--- a/contrib/ast-db-manage/config/env.py
+++ /dev/null
@@ -1,74 +0,0 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
- fileConfig(config.config_file_name)
-except:
- pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
- """Run migrations in 'offline' mode.
-
- This configures the context with just a URL
- and not an Engine, though an Engine is acceptable
- here as well. By skipping the Engine creation
- we don't even need a DBAPI to be available.
-
- Calls to context.execute() here emit the given string to the
- script output.
-
- """
- url = config.get_main_option("sqlalchemy.url")
- context.configure(url=url)
-
- with context.begin_transaction():
- context.run_migrations()
-
-def run_migrations_online():
- """Run migrations in 'online' mode.
-
- In this scenario we need to create an Engine
- and associate a connection with the context.
-
- """
- engine = engine_from_config(
- config.get_section(config.config_ini_section),
- prefix='sqlalchemy.',
- poolclass=pool.NullPool)
-
- connection = engine.connect()
- context.configure(
- connection=connection,
- target_metadata=target_metadata
- )
-
- try:
- with context.begin_transaction():
- context.run_migrations()
- finally:
- connection.close()
-
-if context.is_offline_mode():
- run_migrations_offline()
-else:
- run_migrations_online()
-
diff --git a/contrib/ast-db-manage/config/env.py b/contrib/ast-db-manage/config/env.py
new file mode 120000
index 0000000..74b15c9
--- /dev/null
+++ b/contrib/ast-db-manage/config/env.py
@@ -0,0 +1 @@
+../env.py
\ No newline at end of file
diff --git a/contrib/ast-db-manage/env.py b/contrib/ast-db-manage/env.py
new file mode 100755
index 0000000..a903451
--- /dev/null
+++ b/contrib/ast-db-manage/env.py
@@ -0,0 +1,140 @@
+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.
+config = context.config
+
+# Interpret the config file for Python logging.
+# This line sets up loggers basically.
+try:
+ fileConfig(config.config_file_name)
+except:
+ pass
+
+logger = logging.getLogger('alembic.runtime.setup')
+# add your model's MetaData object here
+# for 'autogenerate' support
+# from myapp import mymodel
+# target_metadata = mymodel.Base.metadata
+target_metadata = None
+
+# other values from the config, defined by the needs of env.py,
+# can be acquired:
+# my_important_option = config.get_main_option("my_important_option")
+# ... etc.
+
+def run_migrations_offline():
+ """Run migrations in 'offline' mode.
+
+ This configures the context with just a URL
+ and not an Engine, though an Engine is acceptable
+ here as well. By skipping the Engine creation
+ we don't even need a DBAPI to be available.
+
+ Calls to context.execute() here emit the given string to the
+ script output.
+
+ """
+ url = config.get_main_option("sqlalchemy.url")
+ context.configure(url=url)
+
+ with context.begin_transaction():
+ context.run_migrations()
+
+def run_migrations_online():
+ """Run migrations in 'online' mode.
+
+ In this scenario we need to create an Engine
+ and associate a connection with the context.
+
+ """
+ engine = engine_from_config(
+ config.get_section(config.config_ini_section),
+ 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,
+ 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 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.')
+ 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():
+ context.run_migrations()
+ finally:
+ connection.close()
+
+
+if context.is_offline_mode():
+ run_migrations_offline()
+else:
+ run_migrations_online()
+
diff --git a/contrib/ast-db-manage/voicemail/env.py b/contrib/ast-db-manage/voicemail/env.py
deleted file mode 100755
index 6740d59..0000000
--- a/contrib/ast-db-manage/voicemail/env.py
+++ /dev/null
@@ -1,74 +0,0 @@
-from __future__ import with_statement
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-from logging.config import fileConfig
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-try:
- fileConfig(config.config_file_name)
-except:
- pass
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-target_metadata = None
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-def run_migrations_offline():
- """Run migrations in 'offline' mode.
-
- This configures the context with just a URL
- and not an Engine, though an Engine is acceptable
- here as well. By skipping the Engine creation
- we don't even need a DBAPI to be available.
-
- Calls to context.execute() here emit the given string to the
- script output.
-
- """
- url = config.get_main_option("sqlalchemy.url")
- context.configure(url=url)
-
- with context.begin_transaction():
- context.run_migrations()
-
-def run_migrations_online():
- """Run migrations in 'online' mode.
-
- In this scenario we need to create an Engine
- and associate a connection with the context.
-
- """
- engine = engine_from_config(
- config.get_section(config.config_ini_section),
- prefix='sqlalchemy.',
- poolclass=pool.NullPool)
-
- connection = engine.connect()
- context.configure(
- connection=connection,
- target_metadata=target_metadata
- )
-
- try:
- with context.begin_transaction():
- context.run_migrations()
- finally:
- connection.close()
-
-if context.is_offline_mode():
- run_migrations_offline()
-else:
- run_migrations_online()
-
diff --git a/contrib/ast-db-manage/voicemail/env.py b/contrib/ast-db-manage/voicemail/env.py
new file mode 120000
index 0000000..74b15c9
--- /dev/null
+++ b/contrib/ast-db-manage/voicemail/env.py
@@ -0,0 +1 @@
+../env.py
\ No newline at end of file
--
To view, visit https://gerrit.asterisk.org/4019
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I4d593f000350deb5d21a14fa1e9bc3896844d898
Gerrit-PatchSet: 2
Gerrit-Project: asterisk
Gerrit-Branch: 14
Gerrit-Owner: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Richard Mudgett <rmudgett at digium.com>
More information about the asterisk-commits
mailing list