Coverage for manila/db/migrations/alembic/versions/1f0bd302c1a6_add_availability_zones_table.py: 100%
47 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
13"""add_availability_zones_table
15Revision ID: 1f0bd302c1a6
16Revises: 579c267fbb4d
17Create Date: 2015-07-24 12:09:36.008570
19"""
21# revision identifiers, used by Alembic.
22revision = '1f0bd302c1a6'
23down_revision = '579c267fbb4d'
25from alembic import op
26from oslo_utils import timeutils
27from oslo_utils import uuidutils
28from sqlalchemy import Column, DateTime, ForeignKey, String, UniqueConstraint
30from manila.db.migrations import utils
33def collect_existing_az_from_services_table(connection, services_table,
34 az_table):
35 az_name_to_id_mapping = dict()
36 existing_az = []
37 for service in connection.execute(services_table.select()):
38 if service.availability_zone in az_name_to_id_mapping:
39 continue
41 az_id = uuidutils.generate_uuid()
42 az_name_to_id_mapping[service.availability_zone] = az_id
43 existing_az.append({
44 'created_at': timeutils.utcnow(),
45 'id': az_id,
46 'name': service.availability_zone
47 })
49 op.bulk_insert(az_table, existing_az)
51 return az_name_to_id_mapping
54def upgrade():
55 connection = op.get_bind()
57 # Create new AZ table and columns
58 availability_zones_table = op.create_table(
59 'availability_zones',
60 Column('created_at', DateTime),
61 Column('updated_at', DateTime),
62 Column('deleted_at', DateTime),
63 Column('deleted', String(length=36), default='False'),
64 Column('id', String(length=36), primary_key=True, nullable=False),
65 Column('name', String(length=255)),
66 UniqueConstraint('name', 'deleted', name='az_name_uc'),
67 mysql_engine='InnoDB',
68 mysql_charset='utf8')
70 for table_name, fk_name in (('services', 'service_az_id_fk'),
71 ('share_instances', 'si_az_id_fk')):
72 op.add_column(
73 table_name,
74 Column('availability_zone_id', String(36),
75 ForeignKey('availability_zones.id', name=fk_name))
76 )
78 # Collect existing AZs from services table
79 services_table = utils.load_table('services', connection)
80 az_name_to_id_mapping = collect_existing_az_from_services_table(
81 connection, services_table, availability_zones_table)
83 # Map string AZ names to ID's in target tables
84 # pylint: disable=no-value-for-parameter
85 set_az_id_in_table = lambda table, id, name: ( # noqa: E731
86 op.execute(
87 table.update().where(table.c.availability_zone == name).values(
88 {'availability_zone_id': id})
89 )
90 )
92 share_instances_table = utils.load_table('share_instances', connection)
93 for name, id in az_name_to_id_mapping.items():
94 for table_name in [services_table, share_instances_table]:
95 set_az_id_in_table(table_name, id, name)
97 # Remove old AZ columns from tables
98 op.drop_column('services', 'availability_zone')
99 op.drop_column('share_instances', 'availability_zone')
102def downgrade():
103 connection = op.get_bind()
105 # Create old AZ fields
106 op.add_column('services', Column('availability_zone', String(length=255)))
107 op.add_column('share_instances',
108 Column('availability_zone', String(length=255)))
110 # Migrate data
111 az_table = utils.load_table('availability_zones', connection)
112 share_instances_table = utils.load_table('share_instances', connection)
113 services_table = utils.load_table('services', connection)
115 for az in connection.execute(az_table.select()):
116 # pylint: disable=no-value-for-parameter
117 op.execute(
118 share_instances_table.update().where(
119 share_instances_table.c.availability_zone_id == az.id
120 ).values({'availability_zone': az.name})
121 )
122 op.execute(
123 services_table.update().where(
124 services_table.c.availability_zone_id == az.id
125 ).values({'availability_zone': az.name})
126 )
128 # Remove AZ_id columns and AZ table
129 op.drop_constraint('service_az_id_fk', 'services', type_='foreignkey')
130 op.drop_column('services', 'availability_zone_id')
131 op.drop_constraint('si_az_id_fk', 'share_instances', type_='foreignkey')
132 op.drop_column('share_instances', 'availability_zone_id')
133 op.drop_table('availability_zones')