1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright (c) 2012 Red Hat, Inc.
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may
7
# not use this file except in compliance with the License. You may obtain
8
# a copy of the License at
10
# http://www.apache.org/licenses/LICENSE-2.0
12
# Unless required by applicable law or agreed to in writing, software
13
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
# License for the specific language governing permissions and limitations
18
from migrate import ForeignKeyConstraint
19
from sqlalchemy import Boolean, Column, DateTime, ForeignKey
20
from sqlalchemy import MetaData, String, Table
23
def upgrade(migrate_engine):
25
meta.bind = migrate_engine
27
# NOTE(dprince): The old dns_domains table is in the 'latin1'
28
# charset and had its primary key length set to 512.
29
# This is too long to be a valid pkey in the 'utf8' table charset
30
# and is the root cause of errors like:
32
# 1) Dumping a database with mysqldump and trying to import it fails
33
# because this table is latin1 but fkeys to utf8 tables (projects).
35
# 2) Trying to alter the old dns_domains table fails with errors like:
36
# mysql> ALTER TABLE dns_domains DROP PRIMARY KEY;
37
# ERROR 1025 (HY000): Error on rename of './nova/#sql-6cf_855'....
39
# In short this table is just in a bad state. So... lets create a new one
40
# with a shorter 'domain' column which is valid for the utf8 charset.
41
# https://bugs.launchpad.net/nova/+bug/993663
44
dns_domains_old = Table('dns_domains', meta, autoload=True)
45
dns_domains_old.rename(name='dns_domains_old')
47
# NOTE(dprince): manually remove pkey/fkey for postgres
48
if migrate_engine.name == "postgresql":
49
sql = """ALTER TABLE ONLY dns_domains_old DROP CONSTRAINT
51
ALTER TABLE ONLY dns_domains_old DROP CONSTRAINT
52
dns_domains_project_id_fkey;"""
53
migrate_engine.execute(sql)
55
#Bind new metadata to avoid issues after the rename
57
meta.bind = migrate_engine
58
projects = Table('projects', meta, autoload=True) # Required for fkey
60
dns_domains_new = Table('dns_domains', meta,
61
Column('created_at', DateTime),
62
Column('updated_at', DateTime),
63
Column('deleted_at', DateTime),
64
Column('deleted', Boolean),
65
Column('domain', String(length=255), nullable=False, primary_key=True),
66
Column('scope', String(length=255)),
67
Column('availability_zone', String(length=255)),
68
Column('project_id', String(length=255), ForeignKey('projects.id')),
69
mysql_engine='InnoDB',
72
dns_domains_new.create()
74
dns_domains_old = Table('dns_domains_old', meta, autoload=True)
75
record_list = list(dns_domains_old.select().execute())
76
for rec in record_list:
77
row = dns_domains_new.insert()
78
row.execute({'created_at': rec['created_at'],
79
'updated_at': rec['updated_at'],
80
'deleted_at': rec['deleted_at'],
81
'deleted': rec['deleted'],
82
'domain': rec['domain'],
83
'scope': rec['scope'],
84
'availability_zone': rec['availability_zone'],
85
'project_id': rec['project_id'],
88
dns_domains_old.drop()
91
def downgrade(migrate_engine):
93
meta.bind = migrate_engine
94
dns_domains_old = Table('dns_domains', meta, autoload=True)
95
dns_domains_old.rename(name='dns_domains_old')
97
# NOTE(dprince): manually remove pkey/fkey for postgres
98
if migrate_engine.name == "postgresql":
99
sql = """ALTER TABLE ONLY dns_domains_old DROP CONSTRAINT
101
ALTER TABLE ONLY dns_domains_old DROP CONSTRAINT
102
dns_domains_project_id_fkey;"""
103
migrate_engine.execute(sql)
105
#Bind new metadata to avoid issues after the rename
107
meta.bind = migrate_engine
109
dns_domains_new = Table('dns_domains', meta,
110
Column('created_at', DateTime),
111
Column('updated_at', DateTime),
112
Column('deleted_at', DateTime),
113
Column('deleted', Boolean),
114
Column('domain', String(length=512), primary_key=True, nullable=False),
115
Column('scope', String(length=255)),
116
Column('availability_zone', String(length=255)),
117
Column('project_id', String(length=255)),
118
mysql_engine='InnoDB',
119
mysql_charset='latin1',
121
dns_domains_new.create()
123
dns_domains_old = Table('dns_domains_old', meta, autoload=True)
124
record_list = list(dns_domains_old.select().execute())
125
for rec in record_list:
126
row = dns_domains_new.insert()
127
row.execute({'created_at': rec['created_at'],
128
'updated_at': rec['updated_at'],
129
'deleted_at': rec['deleted_at'],
130
'deleted': rec['deleted'],
131
'domain': rec['domain'],
132
'scope': rec['scope'],
133
'availability_zone': rec['availability_zone'],
134
'project_id': rec['project_id'],
137
dns_domains_old.drop()
139
# NOTE(dprince): We can't easily add the MySQL Fkey on the downgrade
140
# because projects is 'utf8' where dns_domains is 'latin1'.
141
if migrate_engine.name != "mysql":
142
projects = Table('projects', meta, autoload=True)
143
fkey = ForeignKeyConstraint(columns=[dns_domains_new.c.project_id],
144
refcolumns=[projects.c.id])