
from sqlalchemy import Column, DateTime, MetaData, String, Table


def upgrade(migrate_engine):
    meta = MetaData()
    meta.bind = migrate_engine

    backups = Table('backups', meta, autoload=True)
    snapshot_id = Column('snapshot_id', String(length=36))
    data_timestamp = Column('data_timestamp', DateTime)

    backups.create_column(snapshot_id)
    backups.update().values(snapshot_id=None).execute()

    backups.create_column(data_timestamp)
    backups.update().values(data_timestamp=None).execute()

    # Copy existing created_at timestamp to data_timestamp
    # in the backups table.
    backups_list = list(backups.select().execute())
    for backup in backups_list:
        backup_id = backup.id
        backups.update().\
            where(backups.c.id == backup_id).\
            values(data_timestamp=backup.created_at).execute()


from sqlalchemy import Column, DateTime, MetaData, String, Table


def upgrade(migrate_engine):
    meta = MetaData()
    meta.bind = migrate_engine

    backups = Table('backups', meta, autoload=True)
    snapshot_id = Column('snapshot_id', String(length=36))
    data_timestamp = Column('data_timestamp', DateTime)

    backups.create_column(snapshot_id)

    backups.create_column(data_timestamp)
    backups.update().values(data_timestamp=backups.c.created_at).execute()

Fix race conditions in migration 061
Fix race conditions in migration 061

Migration 061 is supposed to add new `data_timestamp` field and populate
it with value of `created_at` column. This was done by selecting all the
backups and doing updates one-by-one. As it wasn't done in transaction
solution was prone to race condition when a new backup is added while
running the migration. This means that this migration could cause
problems when running in live environment. With blueprint
online-schema-upgrades we want to make Cinder able to perform migrations
live.

A solution is to change this statement to a single DB query which
updates all the rows. This commit also removes unnecessary update to
snapshot_id added there. As this column is nullable it will by default
be NULL, so there's no need to set it manually to that value.

As before and after this commit the migration does logically the same,
this should be safe even if someone is doing inter-release deployments.

An alternative would be to simply add transaction to the update step in
the migration, but that would effectively lock the table for longer
period of time than atomic one-query update.

Closes-Bug: 1530358
Change-Id: Ib8733c096a3dbe2bad00beaf5734936ffcddda33

  
  from sqlalchemy import Column, DateTime, MetaData, String, Table
  
  
  def upgrade(migrate_engine):
      meta = MetaData()
      meta.bind = migrate_engine
  
      backups = Table('backups', meta, autoload=True)
      snapshot_id = Column('snapshot_id', String(length=36))
      data_timestamp = Column('data_timestamp', DateTime)
  
      backups.create_column(snapshot_id)
-     backups.update().values(snapshot_id=None).execute()
  
      backups.create_column(data_timestamp)
-     backups.update().values(data_timestamp=None).execute()
+     backups.update().values(data_timestamp=backups.c.created_at).execute()
  
-     # Copy existing created_at timestamp to data_timestamp
-     # in the backups table.
-     backups_list = list(backups.select().execute())
-     for backup in backups_list:
-         backup_id = backup.id
-         backups.update().\
-             where(backups.c.id == backup_id).\
-             values(data_timestamp=backup.created_at).execute()
- 
Fix race conditions in migration 061
## Code Before:

from sqlalchemy import Column, DateTime, MetaData, String, Table


def upgrade(migrate_engine):
    meta = MetaData()
    meta.bind = migrate_engine

    backups = Table('backups', meta, autoload=True)
    snapshot_id = Column('snapshot_id', String(length=36))
    data_timestamp = Column('data_timestamp', DateTime)

    backups.create_column(snapshot_id)
    backups.update().values(snapshot_id=None).execute()

    backups.create_column(data_timestamp)
    backups.update().values(data_timestamp=None).execute()

    # Copy existing created_at timestamp to data_timestamp
    # in the backups table.
    backups_list = list(backups.select().execute())
    for backup in backups_list:
        backup_id = backup.id
        backups.update().\
            where(backups.c.id == backup_id).\
            values(data_timestamp=backup.created_at).execute()

## Instruction:
Fix race conditions in migration 061
## Code After:

from sqlalchemy import Column, DateTime, MetaData, String, Table


def upgrade(migrate_engine):
    meta = MetaData()
    meta.bind = migrate_engine

    backups = Table('backups', meta, autoload=True)
    snapshot_id = Column('snapshot_id', String(length=36))
    data_timestamp = Column('data_timestamp', DateTime)

    backups.create_column(snapshot_id)

    backups.create_column(data_timestamp)
    backups.update().values(data_timestamp=backups.c.created_at).execute()
