From afd1b9abdbf9b7b037ef144b5915818b4624bc83 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Fri, 9 Nov 2012 15:45:06 +1300 Subject: [PATCH] Switch to UUID for the Stack primary key. For the migrate upgrade, existing integer keys remain and any subsequent stack will be assigned a uuid. For a migrate downgrade, it should work fine if there have been no stacks added since ugrade. Added stacks will have their IDs 'truncated' back to an integer which will require some manual fixup after downgrade. Change-Id: Ib882bece911fcbc96fffab16a9f0e5ce3cb55fed --- .../versions/012_stack_id_uuid.py | 94 +++++++++++++++++++ heat/db/sqlalchemy/models.py | 8 +- 2 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 heat/db/sqlalchemy/migrate_repo/versions/012_stack_id_uuid.py diff --git a/heat/db/sqlalchemy/migrate_repo/versions/012_stack_id_uuid.py b/heat/db/sqlalchemy/migrate_repo/versions/012_stack_id_uuid.py new file mode 100644 index 00000000..b406e4b5 --- /dev/null +++ b/heat/db/sqlalchemy/migrate_repo/versions/012_stack_id_uuid.py @@ -0,0 +1,94 @@ +from sqlalchemy import * +from migrate import * +from heat.common import utils + + +def upgrade(migrate_engine): + meta = MetaData(bind=migrate_engine) + + stack = Table('stack', meta, autoload=True) + event = Table('event', meta, autoload=True) + resource = Table('resource', meta, autoload=True) + + dialect = migrate_engine.url.get_dialect().name + + if not dialect.startswith('sqlite'): + fkeys = list(event.c.stack_id.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint(columns=[event.c.stack_id], + refcolumns=[stack.c.id], + name=fkey_name).drop() + + fkeys = list(resource.c.stack_id.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint(columns=[resource.c.stack_id], + refcolumns=[stack.c.id], + name=fkey_name).drop() + + stack.c.id.alter(String(36), primary_key=True, + default=utils.generate_uuid) + event.c.stack_id.alter(String(36), nullable=False) + resource.c.stack_id.alter(String(36), nullable=False) + + fkeys = list(event.c.stack_id.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint(columns=[event.c.stack_id], + refcolumns=[stack.c.id], + name=fkey_name).create() + + fkeys = list(resource.c.stack_id.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint(columns=[resource.c.stack_id], + refcolumns=[stack.c.id], + name=fkey_name).create() + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + dialect = migrate_engine.url.get_dialect().name + + if dialect.startswith('sqlite'): + return + + stack = Table('stack', meta, autoload=True) + event = Table('event', meta, autoload=True) + resource = Table('resource', meta, autoload=True) + + fkeys = list(event.c.stack_id.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint(columns=[event.c.stack_id], + refcolumns=[stack.c.id], + name=fkey_name).drop() + + fkeys = list(resource.c.stack_id.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint(columns=[resource.c.stack_id], + refcolumns=[stack.c.id], + name=fkey_name).drop() + + stack.c.id.alter(Integer, primary_key=True, + default=utils.generate_uuid) + event.c.stack_id.alter(Integer, nullable=False) + resource.c.stack_id.alter(Integer, nullable=False) + + fkeys = list(event.c.stack_id.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint(columns=[event.c.stack_id], + refcolumns=[stack.c.id], + name=fkey_name).create() + + fkeys = list(resource.c.stack_id.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint(columns=[resource.c.stack_id], + refcolumns=[stack.c.id], + name=fkey_name).create() diff --git a/heat/db/sqlalchemy/models.py b/heat/db/sqlalchemy/models.py index 4e70bdf4..03abeafe 100644 --- a/heat/db/sqlalchemy/models.py +++ b/heat/db/sqlalchemy/models.py @@ -22,6 +22,7 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.schema import ForeignKeyConstraint from sqlalchemy import types as types from json import dumps, loads +from heat.common import utils from heat.openstack.common import timeutils from heat.db.sqlalchemy.session import get_session from sqlalchemy.orm.session import Session @@ -144,7 +145,8 @@ class Stack(BASE, HeatBase): __tablename__ = 'stack' - id = Column(Integer, primary_key=True) + id = Column(String, primary_key=True, + default=utils.generate_uuid) name = Column(String) raw_template_id = Column(Integer, ForeignKey('raw_template.id'), nullable=False) @@ -189,7 +191,7 @@ class Event(BASE, HeatBase): __tablename__ = 'event' id = Column(Integer, primary_key=True) - stack_id = Column(Integer, ForeignKey('stack.id'), + stack_id = Column(String, ForeignKey('stack.id'), nullable=False) stack = relationship(Stack, backref=backref('events')) @@ -215,7 +217,7 @@ class Resource(BASE, HeatBase): # odd name as "metadata" is reserved rsrc_metadata = Column('rsrc_metadata', Json) - stack_id = Column(Integer, ForeignKey('stack.id'), + stack_id = Column(String, ForeignKey('stack.id'), nullable=False) stack = relationship(Stack, backref=backref('resources')) -- 2.45.2