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.
|
||||
|
||||
|
||||
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
|
||||
---------------------------------------------------------------
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user