**** CubicPower OpenStack Study ****
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
nodes = Table('bm_nodes', meta, autoload=True)
ifs = Table('bm_interfaces', meta, autoload=True)
q = select([nodes.c.id, nodes.c.prov_mac_address],
from_obj=nodes)
# Iterate all elements before starting insert since IntegrityError
# may disturb the iteration.
node_address = {}
for node_id, address in q.execute():
node_address[node_id] = address
i = ifs.insert()
for node_id, address in node_address.iteritems():
try:
i.execute({'bm_node_id': node_id, 'address': address})
except exc.IntegrityError:
# The address is registered in both bm_nodes and bm_interfaces.
# It is expected.
pass
**** CubicPower OpenStack Study ****
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
nodes = Table('bm_nodes', meta, autoload=True)
ifs = Table('bm_interfaces', meta, autoload=True)
subq = exists().where(and_(ifs.c.bm_node_id == nodes.c.id,
ifs.c.address == nodes.c.prov_mac_address))
ifs.delete().where(subq).execute()
# NOTE(arata):
# In fact, this downgrade may not return the db to the previous state.
# It seems to be not so match a problem, so this is just for memo.
#
# Think these two state before upgrading:
#
# (A) address 'x' is duplicate
# bm_nodes.prov_mac_address='x'
# bm_interfaces.address=['x', 'y']
#
# (B) no address is duplicate
# bm_nodes.prov_mac_address='x'
# bm_interfaces.address=['y']
#
# Upgrading them results in the same state:
#
# bm_nodes.prov_mac_address='x'
# bm_interfaces.address=['x', 'y']
#
# Downgrading this results in B, even if the actual initial status was A
# Of course we can change it to downgrade to B, but then we cannot
# downgrade to A; it is an exclusive choice since we do not have
# information about the initial state.