91 lines
3.3 KiB
Python
91 lines
3.3 KiB
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.
|
|
|
|
import sqlalchemy
|
|
|
|
from heat.db.sqlalchemy import types as heat_db_types
|
|
from heat.db.sqlalchemy import utils as migrate_utils
|
|
|
|
from migrate import ForeignKeyConstraint
|
|
|
|
|
|
def upgrade(migrate_engine):
|
|
if migrate_engine.name == 'sqlite':
|
|
_upgrade_sqlite(migrate_engine)
|
|
return
|
|
|
|
meta = sqlalchemy.MetaData(bind=migrate_engine)
|
|
|
|
stack = sqlalchemy.Table('stack', meta, autoload=True)
|
|
|
|
prev_raw_template_id = sqlalchemy.Column('prev_raw_template_id',
|
|
sqlalchemy.Integer)
|
|
current_traversal = sqlalchemy.Column('current_traversal',
|
|
sqlalchemy.String(36))
|
|
current_deps = sqlalchemy.Column('current_deps', heat_db_types.Json)
|
|
prev_raw_template_id.create(stack)
|
|
current_traversal.create(stack)
|
|
current_deps.create(stack)
|
|
|
|
raw_template = sqlalchemy.Table('raw_template', meta, autoload=True)
|
|
fkey = ForeignKeyConstraint(columns=[stack.c.prev_raw_template_id],
|
|
refcolumns=[raw_template.c.id],
|
|
name='prev_raw_template_ref')
|
|
fkey.create()
|
|
|
|
|
|
def _upgrade_sqlite(migrate_engine):
|
|
meta = sqlalchemy.MetaData(bind=migrate_engine)
|
|
stack = sqlalchemy.Table('stack', meta, autoload=True)
|
|
table_name = stack.name
|
|
|
|
newcols = [
|
|
sqlalchemy.Column('prev_raw_template_id', sqlalchemy.Integer,
|
|
sqlalchemy.ForeignKey('raw_template.id',
|
|
name='prev_raw_template_ref')),
|
|
sqlalchemy.Column('current_traversal', sqlalchemy.String(36)),
|
|
sqlalchemy.Column('current_deps', heat_db_types.Json),
|
|
]
|
|
|
|
new_stack = migrate_utils.clone_table(table_name + '__tmp__', stack,
|
|
meta, newcols=newcols)
|
|
|
|
# migrate stacks into new table
|
|
stacks = list(stack.select().order_by(
|
|
sqlalchemy.sql.expression.asc(stack.c.created_at))
|
|
.execute())
|
|
colnames = [c.name for c in stack.columns]
|
|
for s in stacks:
|
|
values = dict(zip(colnames,
|
|
map(lambda colname: getattr(s, colname),
|
|
colnames)))
|
|
migrate_engine.execute(new_stack.insert(values))
|
|
|
|
# Drop old tables and rename new ones
|
|
stack.drop()
|
|
new_stack.rename('stack')
|
|
|
|
# add the indexes back
|
|
_add_indexes(migrate_engine, new_stack)
|
|
|
|
|
|
def _add_indexes(migrate_engine, stack):
|
|
name_index = sqlalchemy.Index('ix_stack_name',
|
|
stack.c.name,
|
|
mysql_length=255)
|
|
tenant_index = sqlalchemy.Index('ix_stack_tenant',
|
|
stack.c.tenant,
|
|
mysql_length=255)
|
|
name_index.create(migrate_engine)
|
|
tenant_index.create(migrate_engine)
|