summaryrefslogtreecommitdiff
path: root/heat/db
diff options
context:
space:
mode:
Diffstat (limited to 'heat/db')
-rw-r--r--heat/db/alembic.ini72
-rw-r--r--heat/db/api.py (renamed from heat/db/sqlalchemy/api.py)20
-rw-r--r--heat/db/filters.py (renamed from heat/db/sqlalchemy/filters.py)0
-rw-r--r--heat/db/migration.py117
-rw-r--r--heat/db/migrations/README.rst15
-rw-r--r--heat/db/migrations/env.py94
-rw-r--r--heat/db/migrations/script.py.mako20
-rw-r--r--heat/db/migrations/versions/c6214ca60943_initial_revision.py392
-rw-r--r--heat/db/models.py (renamed from heat/db/sqlalchemy/models.py)2
-rw-r--r--heat/db/sqlalchemy/__init__.py0
-rw-r--r--heat/db/sqlalchemy/migrate_repo/README4
-rw-r--r--heat/db/sqlalchemy/migrate_repo/__init__.py0
-rwxr-xr-xheat/db/sqlalchemy/migrate_repo/manage.py18
-rw-r--r--heat/db/sqlalchemy/migrate_repo/migrate.cfg25
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/073_newton.py387
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/074_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/075_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/076_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/077_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/078_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/079_resource_properties_data.py55
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/080_resource_attrs_data.py31
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/082_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/083_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/084_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/085_placeholder.py20
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/086_drop_watch_rule_watch_data_tables.py53
-rw-r--r--heat/db/sqlalchemy/migrate_repo/versions/__init__.py0
-rw-r--r--heat/db/sqlalchemy/migration.py38
-rw-r--r--heat/db/sqlalchemy/utils.py98
-rw-r--r--heat/db/types.py (renamed from heat/db/sqlalchemy/types.py)0
-rw-r--r--heat/db/utils.py (renamed from heat/db/sqlalchemy/migrate_repo/versions/081_placeholder.py)15
32 files changed, 724 insertions, 912 deletions
diff --git a/heat/db/alembic.ini b/heat/db/alembic.ini
new file mode 100644
index 000000000..dbee79a3b
--- /dev/null
+++ b/heat/db/alembic.ini
@@ -0,0 +1,72 @@
+[alembic]
+# path to migration scripts
+script_location = %(here)s/migrations
+
+# sys.path path, will be prepended to sys.path if present.
+# defaults to the current working directory.
+prepend_sys_path = .
+
+# version location specification; This defaults
+# to heat/db/migrations/versions. When using multiple version
+# directories, initial revisions must be specified with --version-path.
+# The path separator used here should be the separator specified by "version_path_separator" below.
+# version_locations = %(here)s/bar:%(here)s/bat:heat/db/migrations/versions
+
+# version path separator; As mentioned above, this is the character used to split
+# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
+# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
+# Valid values for version_path_separator are:
+#
+# version_path_separator = :
+# version_path_separator = ;
+# version_path_separator = space
+version_path_separator = os # Use os.pathsep. Default configuration used for new projects.
+
+sqlalchemy.url = sqlite:///heat.db
+
+
+[post_write_hooks]
+# post_write_hooks defines scripts or Python functions that are run
+# on newly generated revision scripts. See the documentation for further
+# detail and examples
+
+# format using "black" - use the console_scripts runner, against the "black" entrypoint
+# hooks = black
+# black.type = console_scripts
+# black.entrypoint = black
+# black.options = -l 79 REVISION_SCRIPT_FILENAME
+
+# Logging configuration
+[loggers]
+keys = root,sqlalchemy,alembic
+
+[handlers]
+keys = console
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = WARN
+handlers = console
+qualname =
+
+[logger_sqlalchemy]
+level = WARN
+handlers =
+qualname = sqlalchemy.engine
+
+[logger_alembic]
+level = INFO
+handlers =
+qualname = alembic
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[formatter_generic]
+format = %(levelname)-5.5s [%(name)s] %(message)s
+datefmt = %H:%M:%S
diff --git a/heat/db/sqlalchemy/api.py b/heat/db/api.py
index df627d43c..8b2c99967 100644
--- a/heat/db/sqlalchemy/api.py
+++ b/heat/db/api.py
@@ -38,10 +38,9 @@ from sqlalchemy.orm import aliased as orm_aliased
from heat.common import crypt
from heat.common import exception
from heat.common.i18n import _
-from heat.db.sqlalchemy import filters as db_filters
-from heat.db.sqlalchemy import migration
-from heat.db.sqlalchemy import models
-from heat.db.sqlalchemy import utils as db_utils
+from heat.db import filters as db_filters
+from heat.db import models
+from heat.db import utils as db_utils
from heat.engine import environment as heat_environment
from heat.rpc import api as rpc_api
@@ -1622,19 +1621,6 @@ def sync_point_update_input_data(context, entity_id,
return rows_updated
-def db_sync(engine, version=None):
- """Migrate the database to `version` or the most recent version."""
- if version is not None and int(version) < db_version(engine):
- raise exception.Error(_("Cannot migrate to lower schema version."))
-
- return migration.db_sync(engine, version=version)
-
-
-def db_version(engine):
- """Display the current database version."""
- return migration.db_version(engine)
-
-
def _crypt_action(encrypt):
if encrypt:
return _('encrypt')
diff --git a/heat/db/sqlalchemy/filters.py b/heat/db/filters.py
index 6c7b8cf24..6c7b8cf24 100644
--- a/heat/db/sqlalchemy/filters.py
+++ b/heat/db/filters.py
diff --git a/heat/db/migration.py b/heat/db/migration.py
new file mode 100644
index 000000000..910656ca1
--- /dev/null
+++ b/heat/db/migration.py
@@ -0,0 +1,117 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import os
+
+from alembic import command as alembic_api
+from alembic import config as alembic_config
+from alembic import migration as alembic_migration
+from oslo_log import log as logging
+import sqlalchemy as sa
+
+from heat.db import api as db_api
+
+LOG = logging.getLogger(__name__)
+
+ALEMBIC_INIT_VERSION = 'c6214ca60943'
+
+
+def _migrate_legacy_database(engine, connection, config):
+ """Check if database is a legacy sqlalchemy-migrate-managed database.
+
+ If it is, migrate it by "stamping" the initial alembic schema.
+ """
+ # If the database doesn't have the sqlalchemy-migrate legacy migration
+ # table, we don't have anything to do
+ if not sa.inspect(engine).has_table('migrate_version'):
+ return
+
+ # Likewise, if we've already migrated to alembic, we don't have anything to
+ # do
+ context = alembic_migration.MigrationContext.configure(connection)
+ if context.get_current_revision():
+ return
+
+ # We have legacy migrations but no alembic migration. Stamp (dummy apply)
+ # the initial alembic migration.
+
+ LOG.info(
+ 'The database is still under sqlalchemy-migrate control; '
+ 'fake applying the initial alembic migration'
+ )
+ alembic_api.stamp(config, ALEMBIC_INIT_VERSION)
+
+
+def _find_alembic_conf():
+ """Get the project's alembic configuration
+
+ :returns: An instance of ``alembic.config.Config``
+ """
+ path = os.path.join(
+ os.path.abspath(os.path.dirname(__file__)),
+ 'alembic.ini',
+ )
+ config = alembic_config.Config(os.path.abspath(path))
+ # we don't want to use the logger configuration from the file, which is
+ # only really intended for the CLI
+ # https://stackoverflow.com/a/42691781/613428
+ config.attributes['configure_logger'] = False
+ return config
+
+
+def _upgrade_alembic(engine, config, version):
+ # re-use the connection rather than creating a new one
+ with engine.begin() as connection:
+ config.attributes['connection'] = connection
+ _migrate_legacy_database(engine, connection, config)
+ alembic_api.upgrade(config, version or 'head')
+
+
+def db_sync(version=None, engine=None):
+ """Migrate the database to `version` or the most recent version."""
+ # if the user requested a specific version, check if it's an integer: if
+ # so, we're almost certainly in sqlalchemy-migrate land and won't support
+ # that
+ if version is not None and version.isdigit():
+ raise ValueError(
+ 'You requested an sqlalchemy-migrate database version; this is '
+ 'no longer supported'
+ )
+
+ if engine is None:
+ engine = db_api.get_engine()
+
+ config = _find_alembic_conf()
+
+ # discard the URL encoded in alembic.ini in favour of the URL configured
+ # for the engine by the database fixtures, casting from
+ # 'sqlalchemy.engine.url.URL' to str in the process. This returns a
+ # RFC-1738 quoted URL, which means that a password like "foo@" will be
+ # turned into "foo%40". This in turns causes a problem for
+ # set_main_option() because that uses ConfigParser.set, which (by design)
+ # uses *python* interpolation to write the string out ... where "%" is the
+ # special python interpolation character! Avoid this mismatch by quoting
+ # all %'s for the set below.
+ engine_url = str(engine.url).replace('%', '%%')
+ config.set_main_option('sqlalchemy.url', str(engine_url))
+
+ LOG.info('Applying migration(s)')
+ _upgrade_alembic(engine, config, version)
+ LOG.info('Migration(s) applied')
+
+
+def db_version():
+ """Get database version."""
+ engine = db_api.get_engine()
+ with engine.connect() as connection:
+ m_context = alembic_migration.MigrationContext.configure(connection)
+ return m_context.get_current_revision()
diff --git a/heat/db/migrations/README.rst b/heat/db/migrations/README.rst
new file mode 100644
index 000000000..b2283fc82
--- /dev/null
+++ b/heat/db/migrations/README.rst
@@ -0,0 +1,15 @@
+Database migrations
+===================
+
+This directory contains migrations for the database. These are implemented
+using `alembic`__, a lightweight database migration tool designed for usage
+with `SQLAlchemy`__.
+
+The best place to start understanding Alembic is with its own `tutorial`__. You
+can also play around with the :command:`alembic` command::
+
+ $ alembic --help
+
+.. __: https://alembic.sqlalchemy.org/en/latest/
+.. __: https://www.sqlalchemy.org/
+.. __: https://alembic.sqlalchemy.org/en/latest/tutorial.html
diff --git a/heat/db/migrations/env.py b/heat/db/migrations/env.py
new file mode 100644
index 000000000..932b16a97
--- /dev/null
+++ b/heat/db/migrations/env.py
@@ -0,0 +1,94 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from logging.config import fileConfig
+
+from alembic import context
+from sqlalchemy import engine_from_config
+from sqlalchemy import pool
+
+from heat.db import models
+
+# 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.
+if config.attributes.get('configure_logger', True):
+ fileConfig(config.config_file_name)
+
+# this is the MetaData object for the various models in the database
+target_metadata = models.BASE.metadata
+
+
+def run_migrations_offline() -> None:
+ """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,
+ target_metadata=target_metadata,
+ literal_binds=True,
+ dialect_opts={"paramstyle": "named"},
+ )
+
+ with context.begin_transaction():
+ context.run_migrations()
+
+
+def run_migrations_online() -> None:
+ """Run migrations in 'online' mode.
+
+ In this scenario we need to create an Engine and associate a connection
+ with the context.
+
+ This is modified from the default based on the below, since we want to
+ share an engine when unit testing so in-memory database testing actually
+ works.
+
+ https://alembic.sqlalchemy.org/en/latest/cookbook.html#connection-sharing
+ """
+ connectable = config.attributes.get('connection', None)
+
+ if connectable is None:
+ # only create Engine if we don't have a Connection from the outside
+ connectable = engine_from_config(
+ config.get_section(config.config_ini_section, {}),
+ prefix="sqlalchemy.",
+ poolclass=pool.NullPool,
+ )
+
+ # when connectable is already a Connection object, calling connect() gives
+ # us a *branched connection*
+
+ with connectable.connect() as connection:
+ context.configure(
+ connection=connection,
+ target_metadata=target_metadata,
+ )
+
+ with context.begin_transaction():
+ context.run_migrations()
+
+
+if context.is_offline_mode():
+ run_migrations_offline()
+else:
+ run_migrations_online()
diff --git a/heat/db/migrations/script.py.mako b/heat/db/migrations/script.py.mako
new file mode 100644
index 000000000..120937fbc
--- /dev/null
+++ b/heat/db/migrations/script.py.mako
@@ -0,0 +1,20 @@
+"""${message}
+
+Revision ID: ${up_revision}
+Revises: ${down_revision | comma,n}
+Create Date: ${create_date}
+"""
+
+from alembic import op
+import sqlalchemy as sa
+${imports if imports else ""}
+
+# revision identifiers, used by Alembic.
+revision = ${repr(up_revision)}
+down_revision = ${repr(down_revision)}
+branch_labels = ${repr(branch_labels)}
+depends_on = ${repr(depends_on)}
+
+
+def upgrade() -> None:
+ ${upgrades if upgrades else "pass"}
diff --git a/heat/db/migrations/versions/c6214ca60943_initial_revision.py b/heat/db/migrations/versions/c6214ca60943_initial_revision.py
new file mode 100644
index 000000000..d3e9d757d
--- /dev/null
+++ b/heat/db/migrations/versions/c6214ca60943_initial_revision.py
@@ -0,0 +1,392 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Initial revision
+
+Revision ID: c6214ca60943
+Revises:
+Create Date: 2023-03-22 18:04:02.387269
+"""
+
+from alembic import op
+import sqlalchemy as sa
+
+import heat.db.types
+
+# revision identifiers, used by Alembic.
+revision = 'c6214ca60943'
+down_revision = None
+branch_labels = None
+depends_on = None
+
+
+def upgrade() -> None:
+ op.create_table(
+ 'raw_template_files',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('files', heat.db.types.Json(), nullable=True),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_table(
+ 'resource_properties_data',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('data', heat.db.types.Json(), nullable=True),
+ sa.Column('encrypted', sa.Boolean(), nullable=True),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_table(
+ 'service',
+ sa.Column('id', sa.String(length=36), nullable=False),
+ sa.Column('engine_id', sa.String(length=36), nullable=False),
+ sa.Column('host', sa.String(length=255), nullable=False),
+ sa.Column('hostname', sa.String(length=255), nullable=False),
+ sa.Column('binary', sa.String(length=255), nullable=False),
+ sa.Column('topic', sa.String(length=255), nullable=False),
+ sa.Column('report_interval', sa.Integer(), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('deleted_at', sa.DateTime(), nullable=True),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_table(
+ 'software_config',
+ sa.Column('id', sa.String(length=36), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('name', sa.String(length=255), nullable=True),
+ sa.Column('group', sa.String(length=255), nullable=True),
+ sa.Column('config', heat.db.types.Json(), nullable=True),
+ sa.Column('tenant', sa.String(length=64), nullable=False),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_index(
+ op.f('ix_software_config_tenant'),
+ 'software_config',
+ ['tenant'],
+ unique=False,
+ )
+ op.create_table(
+ 'user_creds',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('username', sa.String(length=255), nullable=True),
+ sa.Column('password', sa.String(length=255), nullable=True),
+ sa.Column('region_name', sa.String(length=255), nullable=True),
+ sa.Column('decrypt_method', sa.String(length=64), nullable=True),
+ sa.Column('tenant', sa.String(length=1024), nullable=True),
+ sa.Column('auth_url', sa.Text(), nullable=True),
+ sa.Column('tenant_id', sa.String(length=256), nullable=True),
+ sa.Column('trust_id', sa.String(length=255), nullable=True),
+ sa.Column('trustor_user_id', sa.String(length=64), nullable=True),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_table(
+ 'raw_template',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('template', heat.db.types.Json(), nullable=True),
+ sa.Column('files', heat.db.types.Json(), nullable=True),
+ sa.Column(
+ 'environment', heat.db.types.Json(), nullable=True
+ ),
+ sa.Column('files_id', sa.Integer(), nullable=True),
+ sa.ForeignKeyConstraint(
+ ['files_id'],
+ ['raw_template_files.id'],
+ name='raw_tmpl_files_fkey_ref',
+ ),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_table(
+ 'software_deployment',
+ sa.Column('id', sa.String(length=36), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('server_id', sa.String(length=36), nullable=False),
+ sa.Column('config_id', sa.String(length=36), nullable=False),
+ sa.Column(
+ 'input_values', heat.db.types.Json(), nullable=True
+ ),
+ sa.Column(
+ 'output_values', heat.db.types.Json(), nullable=True
+ ),
+ sa.Column('action', sa.String(length=255), nullable=True),
+ sa.Column('status', sa.String(length=255), nullable=True),
+ sa.Column('status_reason', sa.Text(), nullable=True),
+ sa.Column('tenant', sa.String(length=64), nullable=False),
+ sa.Column(
+ 'stack_user_project_id', sa.String(length=64), nullable=True
+ ),
+ sa.ForeignKeyConstraint(
+ ['config_id'],
+ ['software_config.id'],
+ ),
+ sa.PrimaryKeyConstraint('id'),
+ )
+ op.create_index(
+ 'ix_software_deployment_created_at',
+ 'software_deployment',
+ ['created_at'],
+ unique=False,
+ )
+ op.create_index(
+ op.f('ix_software_deployment_server_id'),
+ 'software_deployment',
+ ['server_id'],
+ unique=False,
+ )
+ op.create_index(
+ op.f('ix_software_deployment_tenant'),
+ 'software_deployment',
+ ['tenant'],
+ unique=False,
+ )
+ op.create_table(
+ 'stack',
+ sa.Column('id', sa.String(length=36), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('deleted_at', sa.DateTime(), nullable=True),
+ sa.Column('name', sa.String(length=255), nullable=True),
+ sa.Column('raw_template_id', sa.Integer(), nullable=False),
+ sa.Column('prev_raw_template_id', sa.Integer(), nullable=True),
+ sa.Column('user_creds_id', sa.Integer(), nullable=True),
+ sa.Column('username', sa.String(length=256), nullable=True),
+ sa.Column('owner_id', sa.String(length=36), nullable=True),
+ sa.Column('action', sa.String(length=255), nullable=True),
+ sa.Column('status', sa.String(length=255), nullable=True),
+ sa.Column('status_reason', sa.Text(), nullable=True),
+ sa.Column('timeout', sa.Integer(), nullable=True),
+ sa.Column('tenant', sa.String(length=256), nullable=True),
+ sa.Column('disable_rollback', sa.Boolean(), nullable=False),
+ sa.Column(
+ 'stack_user_project_id', sa.String(length=64), nullable=True
+ ),
+ sa.Column('backup', sa.Boolean(), nullable=True),
+ sa.Column('nested_depth', sa.Integer(), nullable=True),
+ sa.Column('convergence', sa.Boolean(), nullable=True),
+ sa.Column('current_traversal', sa.String(length=36), nullable=True),
+ sa.Column(
+ 'current_deps', heat.db.types.Json(), nullable=True
+ ),
+ sa.Column(
+ 'parent_resource_name', sa.String(length=255), nullable=True
+ ),
+ sa.ForeignKeyConstraint(
+ ['prev_raw_template_id'],
+ ['raw_template.id'],
+ ),
+ sa.ForeignKeyConstraint(
+ ['raw_template_id'],
+ ['raw_template.id'],
+ ),
+ sa.ForeignKeyConstraint(
+ ['user_creds_id'],
+ ['user_creds.id'],
+ ),
+ sa.PrimaryKeyConstraint('id'),
+ )
+ op.create_index(
+ 'ix_stack_name', 'stack', ['name'], unique=False, mysql_length=255
+ )
+ op.create_index(
+ 'ix_stack_tenant', 'stack', ['tenant'], unique=False, mysql_length=255
+ )
+ op.create_index(
+ op.f('ix_stack_owner_id'), 'stack', ['owner_id'], unique=False
+ )
+ op.create_table(
+ 'event',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('uuid', sa.String(length=36), nullable=True),
+ sa.Column('stack_id', sa.String(length=36), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('resource_action', sa.String(length=255), nullable=True),
+ sa.Column('resource_status', sa.String(length=255), nullable=True),
+ sa.Column('resource_name', sa.String(length=255), nullable=True),
+ sa.Column(
+ 'physical_resource_id', sa.String(length=255), nullable=True
+ ),
+ sa.Column(
+ 'resource_status_reason', sa.String(length=255), nullable=True
+ ),
+ sa.Column('resource_type', sa.String(length=255), nullable=True),
+ sa.Column('resource_properties', sa.PickleType(), nullable=True),
+ sa.Column('rsrc_prop_data_id', sa.Integer(), nullable=True),
+ sa.ForeignKeyConstraint(
+ ['rsrc_prop_data_id'],
+ ['resource_properties_data.id'],
+ name='ev_rsrc_prop_data_ref',
+ ),
+ sa.ForeignKeyConstraint(
+ ['stack_id'],
+ ['stack.id'],
+ ),
+ sa.PrimaryKeyConstraint('id'),
+ sa.UniqueConstraint('uuid'),
+ mysql_engine='InnoDB',
+ )
+ op.create_table(
+ 'resource',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('uuid', sa.String(length=36), nullable=True),
+ sa.Column('nova_instance', sa.String(length=255), nullable=True),
+ sa.Column('name', sa.String(length=255), nullable=True),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('action', sa.String(length=255), nullable=True),
+ sa.Column('status', sa.String(length=255), nullable=True),
+ sa.Column('status_reason', sa.Text(), nullable=True),
+ sa.Column('stack_id', sa.String(length=36), nullable=False),
+ sa.Column(
+ 'rsrc_metadata', heat.db.types.Json(), nullable=True
+ ),
+ sa.Column(
+ 'properties_data', heat.db.types.Json(), nullable=True
+ ),
+ sa.Column('engine_id', sa.String(length=36), nullable=True),
+ sa.Column('atomic_key', sa.Integer(), nullable=True),
+ sa.Column('needed_by', heat.db.types.List(), nullable=True),
+ sa.Column('requires', heat.db.types.List(), nullable=True),
+ sa.Column('replaces', sa.Integer(), nullable=True),
+ sa.Column('replaced_by', sa.Integer(), nullable=True),
+ sa.Column('current_template_id', sa.Integer(), nullable=True),
+ sa.Column('properties_data_encrypted', sa.Boolean(), nullable=True),
+ sa.Column('root_stack_id', sa.String(length=36), nullable=True),
+ sa.Column('rsrc_prop_data_id', sa.Integer(), nullable=True),
+ sa.Column('attr_data_id', sa.Integer(), nullable=True),
+ sa.ForeignKeyConstraint(
+ ['attr_data_id'],
+ ['resource_properties_data.id'],
+ name='rsrc_attr_data_ref',
+ ),
+ sa.ForeignKeyConstraint(
+ ['current_template_id'],
+ ['raw_template.id'],
+ ),
+ sa.ForeignKeyConstraint(
+ ['rsrc_prop_data_id'],
+ ['resource_properties_data.id'],
+ name='rsrc_rsrc_prop_data_ref',
+ ),
+ sa.ForeignKeyConstraint(
+ ['stack_id'],
+ ['stack.id'],
+ ),
+ sa.PrimaryKeyConstraint('id'),
+ sa.UniqueConstraint('uuid'),
+ mysql_engine='InnoDB',
+ )
+ op.create_index(
+ op.f('ix_resource_root_stack_id'),
+ 'resource',
+ ['root_stack_id'],
+ unique=False,
+ )
+ op.create_table(
+ 'snapshot',
+ sa.Column('id', sa.String(length=36), nullable=False),
+ sa.Column('stack_id', sa.String(length=36), nullable=False),
+ sa.Column('name', sa.String(length=255), nullable=True),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('status', sa.String(length=255), nullable=True),
+ sa.Column('status_reason', sa.String(length=255), nullable=True),
+ sa.Column('data', heat.db.types.Json(), nullable=True),
+ sa.Column('tenant', sa.String(length=64), nullable=False),
+ sa.ForeignKeyConstraint(
+ ['stack_id'],
+ ['stack.id'],
+ ),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_index(
+ op.f('ix_snapshot_tenant'), 'snapshot', ['tenant'], unique=False
+ )
+ op.create_table(
+ 'stack_lock',
+ sa.Column('stack_id', sa.String(length=36), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('engine_id', sa.String(length=36), nullable=True),
+ sa.ForeignKeyConstraint(
+ ['stack_id'],
+ ['stack.id'],
+ ),
+ sa.PrimaryKeyConstraint('stack_id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_table(
+ 'stack_tag',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('tag', sa.Unicode(length=80), nullable=True),
+ sa.Column('stack_id', sa.String(length=36), nullable=False),
+ sa.ForeignKeyConstraint(
+ ['stack_id'],
+ ['stack.id'],
+ ),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
+ op.create_table(
+ 'sync_point',
+ sa.Column('entity_id', sa.String(length=36), nullable=False),
+ sa.Column('traversal_id', sa.String(length=36), nullable=False),
+ sa.Column('is_update', sa.Boolean(), nullable=False),
+ sa.Column('atomic_key', sa.Integer(), nullable=False),
+ sa.Column('stack_id', sa.String(length=36), nullable=False),
+ sa.Column(
+ 'input_data', heat.db.types.Json(), nullable=True
+ ),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.ForeignKeyConstraint(
+ ['stack_id'],
+ ['stack.id'],
+ ),
+ sa.PrimaryKeyConstraint('entity_id', 'traversal_id', 'is_update'),
+ )
+ op.create_table(
+ 'resource_data',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('created_at', sa.DateTime(), nullable=True),
+ sa.Column('updated_at', sa.DateTime(), nullable=True),
+ sa.Column('key', sa.String(length=255), nullable=True),
+ sa.Column('value', sa.Text(), nullable=True),
+ sa.Column('redact', sa.Boolean(), nullable=True),
+ sa.Column('decrypt_method', sa.String(length=64), nullable=True),
+ sa.Column('resource_id', sa.Integer(), nullable=False),
+ sa.ForeignKeyConstraint(
+ ['resource_id'],
+ ['resource.id'],
+ name='fk_resource_id',
+ ondelete='CASCADE',
+ ),
+ sa.PrimaryKeyConstraint('id'),
+ mysql_engine='InnoDB',
+ )
diff --git a/heat/db/sqlalchemy/models.py b/heat/db/models.py
index ca208bef0..ebc235f5d 100644
--- a/heat/db/sqlalchemy/models.py
+++ b/heat/db/models.py
@@ -21,7 +21,7 @@ from sqlalchemy.ext import declarative
from sqlalchemy.orm import backref
from sqlalchemy.orm import relationship
-from heat.db.sqlalchemy import types
+from heat.db import types
BASE = declarative.declarative_base()
diff --git a/heat/db/sqlalchemy/__init__.py b/heat/db/sqlalchemy/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/heat/db/sqlalchemy/__init__.py
+++ /dev/null
diff --git a/heat/db/sqlalchemy/migrate_repo/README b/heat/db/sqlalchemy/migrate_repo/README
deleted file mode 100644
index 131117104..000000000
--- a/heat/db/sqlalchemy/migrate_repo/README
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a database migration repository.
-
-More information at
-https://opendev.org/openstack/sqlalchemy-migrate
diff --git a/heat/db/sqlalchemy/migrate_repo/__init__.py b/heat/db/sqlalchemy/migrate_repo/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/heat/db/sqlalchemy/migrate_repo/__init__.py
+++ /dev/null
diff --git a/heat/db/sqlalchemy/migrate_repo/manage.py b/heat/db/sqlalchemy/migrate_repo/manage.py
deleted file mode 100755
index 41cba1adb..000000000
--- a/heat/db/sqlalchemy/migrate_repo/manage.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from migrate.versioning.shell import main
-
-if __name__ == '__main__':
- main(debug='False')
diff --git a/heat/db/sqlalchemy/migrate_repo/migrate.cfg b/heat/db/sqlalchemy/migrate_repo/migrate.cfg
deleted file mode 100644
index 134fc065d..000000000
--- a/heat/db/sqlalchemy/migrate_repo/migrate.cfg
+++ /dev/null
@@ -1,25 +0,0 @@
-[db_settings]
-# Used to identify which repository this database is versioned under.
-# You can use the name of your project.
-repository_id=heat
-
-# The name of the database table used to track the schema version.
-# This name shouldn't already be used by your project.
-# If this is changed once a database is under version control, you'll need to
-# change the table name in each database too.
-version_table=migrate_version
-
-# When committing a change script, Migrate will attempt to generate the
-# sql for all supported databases; normally, if one of them fails - probably
-# because you don't have that database installed - it is ignored and the
-# commit continues, perhaps ending successfully.
-# Databases in this list MUST compile successfully during a commit, or the
-# entire commit will fail. List the databases your application will actually
-# be using to ensure your updates to that database work properly.
-# This must be a list; example: ['postgres','sqlite']
-required_dbs=[]
-
-# When creating new change scripts, Migrate will stamp the new script with
-# a version number. By default this is latest_version + 1. You can set this
-# to 'true' to tell Migrate to use the UTC timestamp instead.
-use_timestamp_numbering=False
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/073_newton.py b/heat/db/sqlalchemy/migrate_repo/versions/073_newton.py
deleted file mode 100644
index 3293b91ce..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/073_newton.py
+++ /dev/null
@@ -1,387 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import uuid
-
-import sqlalchemy
-
-from heat.db.sqlalchemy import types
-
-
-def upgrade(migrate_engine):
- meta = sqlalchemy.MetaData()
- meta.bind = migrate_engine
-
- raw_template_files = sqlalchemy.Table(
- 'raw_template_files', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer,
- primary_key=True,
- nullable=False),
- sqlalchemy.Column('files', types.Json),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- raw_template = sqlalchemy.Table(
- 'raw_template', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('template', types.LongText),
- sqlalchemy.Column('files', types.Json),
- sqlalchemy.Column('environment', types.Json),
- sqlalchemy.Column('files_id', sqlalchemy.Integer(),
- sqlalchemy.ForeignKey(
- 'raw_template_files.id',
- name='raw_tmpl_files_fkey_ref')),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- user_creds = sqlalchemy.Table(
- 'user_creds', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer,
- primary_key=True, nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('username', sqlalchemy.String(255)),
- sqlalchemy.Column('password', sqlalchemy.String(255)),
- sqlalchemy.Column('region_name', sqlalchemy.String(length=255)),
- sqlalchemy.Column('decrypt_method', sqlalchemy.String(length=64)),
- sqlalchemy.Column('tenant', sqlalchemy.String(1024)),
- sqlalchemy.Column('auth_url', sqlalchemy.Text),
- sqlalchemy.Column('tenant_id', sqlalchemy.String(256)),
- sqlalchemy.Column('trust_id', sqlalchemy.String(255)),
- sqlalchemy.Column('trustor_user_id', sqlalchemy.String(64)),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- stack = sqlalchemy.Table(
- 'stack', meta,
- sqlalchemy.Column('id', sqlalchemy.String(36),
- primary_key=True, nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('deleted_at', sqlalchemy.DateTime),
- sqlalchemy.Column('name', sqlalchemy.String(255)),
- sqlalchemy.Column('raw_template_id',
- sqlalchemy.Integer,
- sqlalchemy.ForeignKey('raw_template.id'),
- nullable=False),
- sqlalchemy.Column('prev_raw_template_id',
- sqlalchemy.Integer,
- sqlalchemy.ForeignKey('raw_template.id')),
- sqlalchemy.Column('user_creds_id', sqlalchemy.Integer,
- sqlalchemy.ForeignKey('user_creds.id')),
- sqlalchemy.Column('username', sqlalchemy.String(256)),
- sqlalchemy.Column('owner_id', sqlalchemy.String(36)),
- sqlalchemy.Column('action', sqlalchemy.String(255)),
- sqlalchemy.Column('status', sqlalchemy.String(255)),
- sqlalchemy.Column('status_reason', sqlalchemy.Text),
- sqlalchemy.Column('timeout', sqlalchemy.Integer),
- sqlalchemy.Column('tenant', sqlalchemy.String(256)),
- sqlalchemy.Column('disable_rollback', sqlalchemy.Boolean,
- nullable=False),
- sqlalchemy.Column('stack_user_project_id',
- sqlalchemy.String(length=64)),
- sqlalchemy.Column('backup', sqlalchemy.Boolean, default=False),
- sqlalchemy.Column('nested_depth', sqlalchemy.Integer, default=0),
- sqlalchemy.Column('convergence', sqlalchemy.Boolean, default=False),
- sqlalchemy.Column('current_traversal', sqlalchemy.String(36)),
- sqlalchemy.Column('current_deps', types.Json),
- sqlalchemy.Column('parent_resource_name', sqlalchemy.String(255)),
- sqlalchemy.Index('ix_stack_name', 'name', mysql_length=255),
- sqlalchemy.Index('ix_stack_tenant', 'tenant', mysql_length=255),
- sqlalchemy.Index('ix_stack_owner_id', 'owner_id', mysql_length=36),
-
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- resource = sqlalchemy.Table(
- 'resource', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True,
- nullable=False),
- sqlalchemy.Column('uuid', sqlalchemy.String(36), unique=True,
- default=lambda: str(uuid.uuid4())),
- sqlalchemy.Column('nova_instance', sqlalchemy.String(255)),
- sqlalchemy.Column('name', sqlalchemy.String(255)),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('action', sqlalchemy.String(255)),
- sqlalchemy.Column('status', sqlalchemy.String(255)),
- sqlalchemy.Column('status_reason', sqlalchemy.Text),
- sqlalchemy.Column('stack_id', sqlalchemy.String(36),
- sqlalchemy.ForeignKey('stack.id'), nullable=False),
- sqlalchemy.Column('rsrc_metadata', types.LongText),
- sqlalchemy.Column('properties_data', types.Json),
- sqlalchemy.Column('engine_id', sqlalchemy.String(length=36)),
- sqlalchemy.Column('atomic_key', sqlalchemy.Integer),
- sqlalchemy.Column('needed_by', types.List),
- sqlalchemy.Column('requires', types.List),
- sqlalchemy.Column('replaces', sqlalchemy.Integer),
- sqlalchemy.Column('replaced_by', sqlalchemy.Integer),
- sqlalchemy.Column('current_template_id', sqlalchemy.Integer,
- sqlalchemy.ForeignKey('raw_template.id')),
- sqlalchemy.Column('properties_data_encrypted',
- sqlalchemy.Boolean,
- default=False),
- sqlalchemy.Column('root_stack_id', sqlalchemy.String(36)),
- sqlalchemy.Index('ix_resource_root_stack_id',
- 'root_stack_id',
- mysql_length=36),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- resource_data = sqlalchemy.Table(
- 'resource_data', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('key', sqlalchemy.String(255)),
- sqlalchemy.Column('value', sqlalchemy.Text),
- sqlalchemy.Column('redact', sqlalchemy.Boolean),
- sqlalchemy.Column('decrypt_method', sqlalchemy.String(length=64)),
- sqlalchemy.Column('resource_id',
- sqlalchemy.Integer,
- sqlalchemy.ForeignKey('resource.id',
- name='fk_resource_id',
- ondelete='CASCADE'),
- nullable=False),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- event = sqlalchemy.Table(
- 'event', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True,
- nullable=False),
- sqlalchemy.Column('uuid', sqlalchemy.String(36),
- default=lambda: str(uuid.uuid4()), unique=True),
- sqlalchemy.Column('stack_id', sqlalchemy.String(36),
- sqlalchemy.ForeignKey('stack.id'), nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('resource_action', sqlalchemy.String(255)),
- sqlalchemy.Column('resource_status', sqlalchemy.String(255)),
- sqlalchemy.Column('resource_name', sqlalchemy.String(255)),
- sqlalchemy.Column('physical_resource_id', sqlalchemy.String(255)),
- sqlalchemy.Column('resource_status_reason', sqlalchemy.String(255)),
- sqlalchemy.Column('resource_type', sqlalchemy.String(255)),
- sqlalchemy.Column('resource_properties', sqlalchemy.PickleType),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- watch_rule = sqlalchemy.Table(
- 'watch_rule', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('name', sqlalchemy.String(255)),
- sqlalchemy.Column('state', sqlalchemy.String(255)),
- sqlalchemy.Column('rule', types.LongText),
- sqlalchemy.Column('last_evaluated', sqlalchemy.DateTime),
- sqlalchemy.Column('stack_id', sqlalchemy.String(36),
- sqlalchemy.ForeignKey('stack.id'), nullable=False),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- watch_data = sqlalchemy.Table(
- 'watch_data', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('data', types.LongText),
- sqlalchemy.Column('watch_rule_id', sqlalchemy.Integer,
- sqlalchemy.ForeignKey('watch_rule.id'),
- nullable=False),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- stack_lock = sqlalchemy.Table(
- 'stack_lock', meta,
- sqlalchemy.Column('stack_id', sqlalchemy.String(length=36),
- sqlalchemy.ForeignKey('stack.id'),
- primary_key=True,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('engine_id', sqlalchemy.String(length=36)),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- software_config = sqlalchemy.Table(
- 'software_config', meta,
- sqlalchemy.Column('id', sqlalchemy.String(36),
- primary_key=True,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('name', sqlalchemy.String(255)),
- sqlalchemy.Column('group', sqlalchemy.String(255)),
- sqlalchemy.Column('config', types.LongText),
- sqlalchemy.Column('tenant', sqlalchemy.String(64),
- nullable=False,
- index=True),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- software_deployment = sqlalchemy.Table(
- 'software_deployment', meta,
- sqlalchemy.Column('id', sqlalchemy.String(36),
- primary_key=True,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime,
- index=True),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('server_id', sqlalchemy.String(36),
- nullable=False,
- index=True),
- sqlalchemy.Column('config_id',
- sqlalchemy.String(36),
- sqlalchemy.ForeignKey('software_config.id'),
- nullable=False),
- sqlalchemy.Column('input_values', types.Json),
- sqlalchemy.Column('output_values', types.Json),
- sqlalchemy.Column('action', sqlalchemy.String(255)),
- sqlalchemy.Column('status', sqlalchemy.String(255)),
- sqlalchemy.Column('status_reason', sqlalchemy.Text),
- sqlalchemy.Column('tenant', sqlalchemy.String(64),
- nullable=False,
- index=True),
- sqlalchemy.Column('stack_user_project_id',
- sqlalchemy.String(length=64)),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- snapshot = sqlalchemy.Table(
- 'snapshot', meta,
- sqlalchemy.Column('id', sqlalchemy.String(36),
- primary_key=True,
- nullable=False),
- sqlalchemy.Column('stack_id',
- sqlalchemy.String(36),
- sqlalchemy.ForeignKey('stack.id'),
- nullable=False),
- sqlalchemy.Column('name', sqlalchemy.String(255)),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('status', sqlalchemy.String(255)),
- sqlalchemy.Column('status_reason', sqlalchemy.String(255)),
- sqlalchemy.Column('data', types.Json),
- sqlalchemy.Column('tenant', sqlalchemy.String(64),
- nullable=False,
- index=True),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- service = sqlalchemy.Table(
- 'service', meta,
- sqlalchemy.Column('id', sqlalchemy.String(36), primary_key=True,
- default=lambda: str(uuid.uuid4())),
- sqlalchemy.Column('engine_id', sqlalchemy.String(36), nullable=False),
- sqlalchemy.Column('host', sqlalchemy.String(255), nullable=False),
- sqlalchemy.Column('hostname', sqlalchemy.String(255), nullable=False),
- sqlalchemy.Column('binary', sqlalchemy.String(255), nullable=False),
- sqlalchemy.Column('topic', sqlalchemy.String(255), nullable=False),
- sqlalchemy.Column('report_interval', sqlalchemy.Integer,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('deleted_at', sqlalchemy.DateTime),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- stack_tag = sqlalchemy.Table(
- 'stack_tag', meta,
- sqlalchemy.Column('id',
- sqlalchemy.Integer,
- primary_key=True,
- nullable=False),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- sqlalchemy.Column('tag', sqlalchemy.Unicode(80)),
- sqlalchemy.Column('stack_id',
- sqlalchemy.String(36),
- sqlalchemy.ForeignKey('stack.id'),
- nullable=False),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- sync_point = sqlalchemy.Table(
- 'sync_point', meta,
- sqlalchemy.Column('entity_id', sqlalchemy.String(36)),
- sqlalchemy.Column('traversal_id', sqlalchemy.String(36)),
- sqlalchemy.Column('is_update', sqlalchemy.Boolean),
- sqlalchemy.Column('atomic_key', sqlalchemy.Integer,
- nullable=False),
- sqlalchemy.Column('stack_id', sqlalchemy.String(36),
- nullable=False),
- sqlalchemy.Column('input_data', types.Json),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
-
- sqlalchemy.PrimaryKeyConstraint('entity_id',
- 'traversal_id',
- 'is_update'),
- sqlalchemy.ForeignKeyConstraint(['stack_id'], ['stack.id'],
- name='fk_stack_id'),
-
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
-
- tables = (
- raw_template_files,
- raw_template,
- user_creds,
- stack,
- resource,
- resource_data,
- event,
- watch_rule,
- watch_data,
- stack_lock,
- software_config,
- software_deployment,
- snapshot,
- service,
- stack_tag,
- sync_point,
- )
-
- for index, table in enumerate(tables):
- try:
- table.create()
- except Exception:
- # If an error occurs, drop all tables created so far to return
- # to the previously existing state.
- meta.drop_all(tables=tables[:index])
- raise
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/074_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/074_placeholder.py
deleted file mode 100644
index e46d47580..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/074_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Newton backports.
-# Do not use this number for new Ocata work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/075_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/075_placeholder.py
deleted file mode 100644
index e46d47580..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/075_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Newton backports.
-# Do not use this number for new Ocata work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/076_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/076_placeholder.py
deleted file mode 100644
index e46d47580..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/076_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Newton backports.
-# Do not use this number for new Ocata work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/077_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/077_placeholder.py
deleted file mode 100644
index e46d47580..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/077_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Newton backports.
-# Do not use this number for new Ocata work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/078_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/078_placeholder.py
deleted file mode 100644
index e46d47580..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/078_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Newton backports.
-# Do not use this number for new Ocata work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/079_resource_properties_data.py b/heat/db/sqlalchemy/migrate_repo/versions/079_resource_properties_data.py
deleted file mode 100644
index 574450654..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/079_resource_properties_data.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from migrate.changeset import constraint
-import sqlalchemy
-
-from heat.db.sqlalchemy import types
-
-
-def upgrade(migrate_engine):
- meta = sqlalchemy.MetaData(bind=migrate_engine)
-
- resource_properties_data = sqlalchemy.Table(
- 'resource_properties_data', meta,
- sqlalchemy.Column('id', sqlalchemy.Integer,
- primary_key=True,
- nullable=False),
- sqlalchemy.Column('data', types.Json),
- sqlalchemy.Column('encrypted', sqlalchemy.Boolean),
- sqlalchemy.Column('created_at', sqlalchemy.DateTime),
- sqlalchemy.Column('updated_at', sqlalchemy.DateTime),
- mysql_engine='InnoDB',
- mysql_charset='utf8'
- )
- resource_properties_data.create()
-
- resource = sqlalchemy.Table('resource', meta, autoload=True)
- rsrc_prop_data_id = sqlalchemy.Column('rsrc_prop_data_id',
- sqlalchemy.Integer)
- rsrc_prop_data_id.create(resource)
- res_fkey = constraint.ForeignKeyConstraint(
- columns=[resource.c.rsrc_prop_data_id],
- refcolumns=[resource_properties_data.c.id],
- name='rsrc_rsrc_prop_data_ref')
- res_fkey.create()
-
- event = sqlalchemy.Table('event', meta, autoload=True)
- rsrc_prop_data_id = sqlalchemy.Column('rsrc_prop_data_id',
- sqlalchemy.Integer)
- rsrc_prop_data_id.create(event)
- ev_fkey = constraint.ForeignKeyConstraint(
- columns=[event.c.rsrc_prop_data_id],
- refcolumns=[resource_properties_data.c.id],
- name='ev_rsrc_prop_data_ref')
- ev_fkey.create()
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/080_resource_attrs_data.py b/heat/db/sqlalchemy/migrate_repo/versions/080_resource_attrs_data.py
deleted file mode 100644
index 4636d1e76..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/080_resource_attrs_data.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from migrate.changeset import constraint
-import sqlalchemy
-
-
-def upgrade(migrate_engine):
- meta = sqlalchemy.MetaData(bind=migrate_engine)
-
- resource = sqlalchemy.Table('resource', meta, autoload=True)
- resource_properties_data = sqlalchemy.Table('resource_properties_data',
- meta, autoload=True)
- attr_data_id = sqlalchemy.Column('attr_data_id',
- sqlalchemy.Integer)
- attr_data_id.create(resource)
- res_fkey = constraint.ForeignKeyConstraint(
- columns=[resource.c.attr_data_id],
- refcolumns=[resource_properties_data.c.id],
- name='rsrc_attr_data_ref')
- res_fkey.create()
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/082_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/082_placeholder.py
deleted file mode 100644
index 4378ff335..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/082_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Pike backports.
-# Do not use this number for new Queens work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/083_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/083_placeholder.py
deleted file mode 100644
index 4378ff335..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/083_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Pike backports.
-# Do not use this number for new Queens work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/084_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/084_placeholder.py
deleted file mode 100644
index 4378ff335..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/084_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Pike backports.
-# Do not use this number for new Queens work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/085_placeholder.py b/heat/db/sqlalchemy/migrate_repo/versions/085_placeholder.py
deleted file mode 100644
index 4378ff335..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/085_placeholder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is a placeholder for Pike backports.
-# Do not use this number for new Queens work, which starts after
-# all the placeholders.
-
-
-def upgrade(migrate_engine):
- pass
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/086_drop_watch_rule_watch_data_tables.py b/heat/db/sqlalchemy/migrate_repo/versions/086_drop_watch_rule_watch_data_tables.py
deleted file mode 100644
index a99ac5c4e..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/086_drop_watch_rule_watch_data_tables.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from migrate import ForeignKeyConstraint
-from sqlalchemy.engine import reflection
-from sqlalchemy import MetaData
-from sqlalchemy import Table
-
-
-def upgrade(engine):
- meta = MetaData()
- meta.bind = engine
-
- def _get_columns(source_table, params):
- columns = set()
- for column in params:
- columns.add(source_table.c[column])
- return columns
-
- def _remove_foreign_key_constraints(engine, meta, table_name):
- inspector = reflection.Inspector.from_engine(engine)
-
- for fk in inspector.get_foreign_keys(table_name):
- source_table = Table(table_name, meta, autoload=True)
- target_table = Table(fk['referred_table'], meta, autoload=True)
-
- fkey = ForeignKeyConstraint(
- columns=_get_columns(source_table, fk['constrained_columns']),
- refcolumns=_get_columns(target_table, fk['referred_columns']),
- name=fk['name'])
- fkey.drop()
-
- def _drop_table_and_indexes(meta, table_name):
- table = Table(table_name, meta, autoload=True)
- for index in table.indexes:
- index.drop()
- table.drop()
-
- table_names = ('watch_data', 'watch_rule')
-
- for table_name in table_names:
- _remove_foreign_key_constraints(engine, meta, table_name)
- _drop_table_and_indexes(meta, table_name)
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/__init__.py b/heat/db/sqlalchemy/migrate_repo/versions/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/heat/db/sqlalchemy/migrate_repo/versions/__init__.py
+++ /dev/null
diff --git a/heat/db/sqlalchemy/migration.py b/heat/db/sqlalchemy/migration.py
deleted file mode 100644
index 7f030d90a..000000000
--- a/heat/db/sqlalchemy/migration.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import os
-
-from oslo_db.sqlalchemy import migration as oslo_migration
-
-
-INIT_VERSION = 72
-
-
-def db_sync(engine, version=None):
- path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
- 'migrate_repo')
- return oslo_migration.db_sync(engine, path, version,
- init_version=INIT_VERSION)
-
-
-def db_version(engine):
- path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
- 'migrate_repo')
- return oslo_migration.db_version(engine, path, INIT_VERSION)
-
-
-def db_version_control(engine, version=None):
- path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
- 'migrate_repo')
- return oslo_migration.db_version_control(engine, path, version)
diff --git a/heat/db/sqlalchemy/utils.py b/heat/db/sqlalchemy/utils.py
deleted file mode 100644
index 5fff4f763..000000000
--- a/heat/db/sqlalchemy/utils.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# SQLAlchemy helper functions
-
-import sqlalchemy
-from sqlalchemy.orm import exc
-import tenacity
-
-
-def clone_table(name, parent, meta, newcols=None, ignorecols=None,
- swapcols=None, ignorecons=None):
- """Helper function that clones parent table schema onto new table.
-
- :param name: new table name
- :param parent: parent table to copy schema from
- :param newcols: names of new columns to be added
- :param ignorecols: names of columns to be ignored while cloning
- :param swapcols: alternative column schema
- :param ignorecons: names of constraints to be ignored
-
- :return: sqlalchemy.Table instance
- """
-
- newcols = newcols or []
- ignorecols = ignorecols or []
- swapcols = swapcols or {}
- ignorecons = ignorecons or []
-
- cols = [c.copy() for c in parent.columns
- if c.name not in ignorecols
- if c.name not in swapcols]
- cols.extend(swapcols.values())
- cols.extend(newcols)
- new_table = sqlalchemy.Table(name, meta, *(cols))
-
- def _is_ignorable(cons):
- # consider constraints on columns only
- if hasattr(cons, 'columns'):
- for col in ignorecols:
- if col in cons.columns:
- return True
-
- return False
-
- constraints = [c.copy(target_table=new_table) for c in parent.constraints
- if c.name not in ignorecons
- if not _is_ignorable(c)]
-
- for c in constraints:
- new_table.append_constraint(c)
-
- new_table.create()
- return new_table
-
-
-def migrate_data(migrate_engine,
- table,
- new_table,
- skip_columns=None):
-
- table_name = table.name
-
- list_of_rows = list(table.select().execute())
-
- colnames = [c.name for c in table.columns]
-
- for row in list_of_rows:
- values = dict(zip(colnames,
- map(lambda colname: getattr(row, colname),
- colnames)))
- if skip_columns is not None:
- for column in skip_columns:
- del values[column]
-
- migrate_engine.execute(new_table.insert(values))
-
- table.drop()
-
- new_table.rename(table_name)
-
-
-def retry_on_stale_data_error(func):
- wrapper = tenacity.retry(
- stop=tenacity.stop_after_attempt(3),
- retry=tenacity.retry_if_exception_type(exc.StaleDataError),
- reraise=True)
- return wrapper(func)
diff --git a/heat/db/sqlalchemy/types.py b/heat/db/types.py
index d454024c6..d454024c6 100644
--- a/heat/db/sqlalchemy/types.py
+++ b/heat/db/types.py
diff --git a/heat/db/sqlalchemy/migrate_repo/versions/081_placeholder.py b/heat/db/utils.py
index 4378ff335..67e2d541e 100644
--- a/heat/db/sqlalchemy/migrate_repo/versions/081_placeholder.py
+++ b/heat/db/utils.py
@@ -11,10 +11,15 @@
# License for the specific language governing permissions and limitations
# under the License.
-# This is a placeholder for Pike backports.
-# Do not use this number for new Queens work, which starts after
-# all the placeholders.
+# SQLAlchemy helper functions
+from sqlalchemy.orm import exc
+import tenacity
-def upgrade(migrate_engine):
- pass
+
+def retry_on_stale_data_error(func):
+ wrapper = tenacity.retry(
+ stop=tenacity.stop_after_attempt(3),
+ retry=tenacity.retry_if_exception_type(exc.StaleDataError),
+ reraise=True)
+ return wrapper(func)