Merge "[devref] db_layer: expand on how new migration scripts look like"
This commit is contained in:
commit
3cc16ad377
@ -64,6 +64,111 @@ It will apply all the rules from both the expand and the contract branches, in
|
|||||||
proper order.
|
proper order.
|
||||||
|
|
||||||
|
|
||||||
|
Expand and Contract Scripts
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
The obsolete "branchless" design of a migration script included that it
|
||||||
|
indicates a specific "version" of the schema, and includes directives that
|
||||||
|
apply all necessary changes to the database at once. If we look for example at
|
||||||
|
the script ``2d2a8a565438_hierarchical_binding.py``, we will see::
|
||||||
|
|
||||||
|
# .../alembic_migrations/versions/2d2a8a565438_hierarchical_binding.py
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
|
||||||
|
# .. inspection code ...
|
||||||
|
|
||||||
|
op.create_table(
|
||||||
|
'ml2_port_binding_levels',
|
||||||
|
sa.Column('port_id', sa.String(length=36), nullable=False),
|
||||||
|
sa.Column('host', sa.String(length=255), nullable=False),
|
||||||
|
# ... more columns ...
|
||||||
|
)
|
||||||
|
|
||||||
|
for table in port_binding_tables:
|
||||||
|
op.execute((
|
||||||
|
"INSERT INTO ml2_port_binding_levels "
|
||||||
|
"SELECT port_id, host, 0 AS level, driver, segment AS segment_id "
|
||||||
|
"FROM %s "
|
||||||
|
"WHERE host <> '' "
|
||||||
|
"AND driver <> '';"
|
||||||
|
) % table)
|
||||||
|
|
||||||
|
op.drop_constraint(fk_name_dvr[0], 'ml2_dvr_port_bindings', 'foreignkey')
|
||||||
|
op.drop_column('ml2_dvr_port_bindings', 'cap_port_filter')
|
||||||
|
op.drop_column('ml2_dvr_port_bindings', 'segment')
|
||||||
|
op.drop_column('ml2_dvr_port_bindings', 'driver')
|
||||||
|
|
||||||
|
# ... more DROP instructions ...
|
||||||
|
|
||||||
|
The above script contains directives that are both under the "expand"
|
||||||
|
and "contract" categories, as well as some data migrations. the ``op.create_table``
|
||||||
|
directive is an "expand"; it may be run safely while the old version of the
|
||||||
|
application still runs, as the old code simply doesn't look for this table.
|
||||||
|
The ``op.drop_constraint`` and ``op.drop_column`` directives are
|
||||||
|
"contract" directives (the drop column moreso than the drop constraint); running
|
||||||
|
at least the ``op.drop_column`` directives means that the old version of the
|
||||||
|
application will fail, as it will attempt to access these columns which no longer
|
||||||
|
exist.
|
||||||
|
|
||||||
|
The data migrations in this script are adding new
|
||||||
|
rows to the newly added ``ml2_port_binding_levels`` table.
|
||||||
|
|
||||||
|
Under the new migration script directory structure, the above script would be
|
||||||
|
stated as two scripts; an "expand" and a "contract" script::
|
||||||
|
|
||||||
|
# expansion operations
|
||||||
|
# .../alembic_migrations/versions/liberty/expand/2bde560fc638_hierarchical_binding.py
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
|
||||||
|
op.create_table(
|
||||||
|
'ml2_port_binding_levels',
|
||||||
|
sa.Column('port_id', sa.String(length=36), nullable=False),
|
||||||
|
sa.Column('host', sa.String(length=255), nullable=False),
|
||||||
|
# ... more columns ...
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# contraction operations
|
||||||
|
# .../alembic_migrations/versions/liberty/contract/4405aedc050e_hierarchical_binding.py
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
|
||||||
|
for table in port_binding_tables:
|
||||||
|
op.execute((
|
||||||
|
"INSERT INTO ml2_port_binding_levels "
|
||||||
|
"SELECT port_id, host, 0 AS level, driver, segment AS segment_id "
|
||||||
|
"FROM %s "
|
||||||
|
"WHERE host <> '' "
|
||||||
|
"AND driver <> '';"
|
||||||
|
) % table)
|
||||||
|
|
||||||
|
op.drop_constraint(fk_name_dvr[0], 'ml2_dvr_port_bindings', 'foreignkey')
|
||||||
|
op.drop_column('ml2_dvr_port_bindings', 'cap_port_filter')
|
||||||
|
op.drop_column('ml2_dvr_port_bindings', 'segment')
|
||||||
|
op.drop_column('ml2_dvr_port_bindings', 'driver')
|
||||||
|
|
||||||
|
# ... more DROP instructions ...
|
||||||
|
|
||||||
|
The two scripts would be present in different subdirectories and also part of
|
||||||
|
entirely separate versioning streams. The "expand" operations are in the
|
||||||
|
"expand" script, and the "contract" operations are in the "contract" script.
|
||||||
|
|
||||||
|
For the time being, data migration rules also belong to contract branch. There
|
||||||
|
is expectation that eventually live data migrations move into middleware that
|
||||||
|
will be aware about different database schema elements to converge on, but
|
||||||
|
Neutron is still not there.
|
||||||
|
|
||||||
|
Scripts that contain only expansion or contraction rules do not require a split
|
||||||
|
into two parts.
|
||||||
|
|
||||||
|
If a contraction script depends on a script from expansion stream, the
|
||||||
|
following directive should be added in the contraction script::
|
||||||
|
|
||||||
|
depends_on = ('<expansion-revision>',)
|
||||||
|
|
||||||
|
|
||||||
Tests to verify that database migrations and models are in sync
|
Tests to verify that database migrations and models are in sync
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user