Neutron Database Layer

This section contains some common information that will be useful for developers that need to do some db changes.

Difference between ‘default’ and ‘server_default’ parameters for columns

For columns it is possible to set ‘default’ or ‘server_default’. What is the difference between them and why should they be used?

The explanation is quite simple:

  • default - the default value that SQLAlchemy will specify in queries for creating instances of a given model;
  • server_default - the default value for a column that SQLAlchemy will specify in DDL.

Summarizing, ‘default’ is useless in migrations and only ‘server_default’ should be used. For synchronizing migrations with models server_default parameter should also be added in model. If default value in database is not needed, ‘server_default’ should not be used. The declarative approach can be bypassed (i.e. ‘default’ may be omitted in the model) if default is enforced through business logic.

Database migrations

For details on the neutron-db-manage wrapper and alembic migrations, see Alembic Migrations.

Tests to verify that database migrations and models are in sync

class neutron.tests.functional.db.test_migrations._TestModelsMigrations

Test for checking of equality models state and migrations.

For the opportunistic testing you need to set up a db named ‘openstack_citest’ with user ‘openstack_citest’ and password ‘openstack_citest’ on localhost. The test will then use that db and user/password combo to run the tests.

For PostgreSQL on Ubuntu this can be done with the following commands:

sudo -u postgres psql
postgres=# create user openstack_citest with createdb login password
          'openstack_citest';
postgres=# create database openstack_citest with owner
           openstack_citest;

For MySQL on Ubuntu this can be done with the following commands:

mysql -u root
>create database openstack_citest;
>grant all privileges on openstack_citest.* to
 openstack_citest@localhost identified by 'openstack_citest';

Output is a list that contains information about differences between db and models. Output example:

[('add_table',
  Table('bat', MetaData(bind=None),
        Column('info', String(), table=<bat>), schema=None)),
 ('remove_table',
  Table(u'bar', MetaData(bind=None),
        Column(u'data', VARCHAR(), table=<bar>), schema=None)),
 ('add_column',
  None,
  'foo',
  Column('data', Integer(), table=<foo>)),
 ('remove_column',
  None,
  'foo',
  Column(u'old_data', VARCHAR(), table=None)),
 [('modify_nullable',
   None,
   'foo',
   u'x',
   {'existing_server_default': None,
   'existing_type': INTEGER()},
   True,
   False)]]
  • remove_* means that there is extra table/column/constraint in db;

  • add_* means that it is missing in db;

  • modify_* means that on column in db is set wrong type/nullable/server_default. Element contains information:

    • what should be modified,
    • schema,
    • table,
    • column,
    • existing correct column parameters,
    • right value,
    • wrong value.